On Wed 08 May 2002 at 02:10:58 +0900, Lars Christensen wrote:

> On Wed, 8 May 2002 nobu.nokada / softhome.net wrote:
>
> > Hi,
> >
> > At Tue, 7 May 2002 23:33:50 +0900,
> > Lars Christensen wrote:
> > > I'm puzzled why this doesn't work the way I expect it to.
> > >
> > > "xxoxxxoxx" =~ /(?!x)ox+o(?!x)/      #=> nil (ok)
> > > "xx oxxxoxx" =~ /(?!x)ox+o(?!x)/     #=> nil (ok)
> > > "xx oxxxo xx" =~ /(?!x)ox+o(?!x)/    #=> 3 (ok)
> > > "xxoxxxo xx" =~ /(?!x)ox+o(?!x)/     #=> 2 (huh!?)
> > >
> > > Why is the string matched in the last case?
> >
> > Already pointed out the reason, however you really want look
> > behind?
> >
> > "xxoxxxo xx" =~ /(?<!x)ox+o(?!x)/      #=> nil (with Oniguruma)
>
> Yes, this is was what I am missing.
>
> My current work-around is /([^x]|^)ox+o(?!x)/, but then I need to prepend
> \$1 to the replacement, e.g.

This will work, too, and doesn't require the \$1:

/(?!x).ox+o(?!x)/

> str.gsub(/([^x]|^)ox+o(?!x)/) { \$1 + "replacement" }
>
> .. and it gets even worse/impossible if one wants to non-match multiple
> characters.

If the number of characters is multiple, but always the same number,
then you can just increase the number of 'x' and the number of '.'
proportionally:

/(?!xx)..ox+o/		to match 'ox+o' not preceded by 'xx'
/(?!xxx)...ox+o/	to match 'ox+o' not preceded by 'xxx'
/(?!xxxx)....ox+o/	to match 'ox+o' not preceded by 'xxxx'

At this point, this probably becomes better:
/(?!x{5}).{5}ox+o/	to match 'ox+o' not preceded by 'xxxxx'

Ian
--
Ian Macdonald               | "Truth is stranger than fiction, because
ian / caliban.org             | fiction has to make sense."
|
|
|