From: Jeff Davis Date: 2005-01-28T03:57:07+09:00 Subject: Re: regex questions Jacob Fugal wrote: >On Thu, 27 Jan 2005 16:10:59 +0900, Andrew Johnson wrote: > > >>A fairly standard way is to use negative look-ahead and inch >>ahead one character at a time like: >> >> re = %r{a((?:(?!foo).)*?)b} >> >> > >Thank you, oh thank you! I don't know how many times I've been told >that something like this was possible, but neither I nor the "guru" >who told me could make it work. You have my eternal gratitude! > >Jacob Fugal > > > > Another way is kind of complicated, but it works. Let's say that you want to match a string like: if str =~ /a(.*)b/ and str !~ /a(.*xyz.*)b/ then you can instead do: if str =~ /[^a]*a([^bx]|x[^by]|xy[^bz])*(b|xb|xyb)/ [ I changed to 'xyz' from 'foo' to show what's going on in the regex better ] It's nice to have one regex like that, but you can see that it gets complicated and hard to read, especially as the string you're avoiding (in this case xyz) turns into a complicated regex. Technically, you can build any regular expression with only "()", "|" and "*" (and of course concatenation, which is just two expressions next to eachother, no operator is needed). Andrew's is much more readable, however. Regards, Jeff Davis Note: I know I answered my own question. I did a little research about regexes first. Thanks Andrew for the negative-lookahead thing, that's what I was looking for.