Sunday, September 7, 2008

Finding The Opposite Of A Regular Expression In Ruby

I don't know if it happened to you but there are some times when you want to find the contrary of what you have in mind, I mean the opposite (inverse) of a regular expression or everything except a certain regexp. Well, there is a way to achieve that with Ruby (and a lot of other programming languages):
/^((?!REGULAR_EXPRESSION_HERE).)*$/


For example, if you want to find every lines where the first character is NOT 2 to 4 "f" followed by "oo" and then "bar" somewhere else on the line, you can use:
/^((?!^f{2,4}oo.*bar).)*$/

Example:
"foo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] => "foo+bar"

"fffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] => nil

" fffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] => " fffoo+bar"

"fffffoo+bar"[/^((?!^f{2,4}oo.*bar).)*$/] => "fffffoo+bar"


For the references, those ideas came from the Vim tips section here.

I hope this will help someone.

4 comments:

Emmanuel said...

Mmmmm, I'm sure this will turn out useful someday... :) Thanks.

P.S.: Since ruby let you interpolate expressions inside regexps, you could do it like this:

class Regexp
def negated
/^((?!#{ self }).)*$/
end
end

"1 2 3" =~ /2/ # => 2
"1 2 3" =~ /2/.negated # => nil

Michael Wong said...

hi, any interest in exchanging blog roll links with a PR5 blog? if yes, leave your blog url as a comment at:
http://bigmoneylist.blogspot.com
i'll link to you first, then when you have time, link back. :)

Wolf said...

Regular expression is really wonderful to parsing HTML or matching pattern. I use this a lot when i code. Actually when I learn any new langauge, first of all I first try whether it supports regex or not. I feel ezee when I found that.

http://icfun.blogspot.com/2008/04/ruby-regular-expression-handling.html

Here is about ruby regex. This was posted by me when I first learn ruby regex. So it will be helpfull for New coders.

Rory McCann said...

You can also do this (in python) by 'splitting' the string based on the regular expression. I'm sure ruby has a similar 'regex split'.

invert a regular expression