From: "Jenda Krynicky" <[EMAIL PROTECTED]>
> From: [EMAIL PROTECTED]
> > How can I compose a pattern for strings which _don't_ contain
> > "stuff"?
> >
> > My code contains $x =~ $pattern; I can't change this. Now I must
> > define my $pattern to determine whether $x _doesn't_ contain
> > "stuff".
> >
> > I've been over perlrequick and perlretut, but all examples of
> > "doesn't contain" use a negative operator (!~) instead of a negative
> > expression.
>
> You can often do this using the negative look-ahead (?!...).
>
> Assuming the stuff that is not allowed is "stuff". Then the regexp
> could be like this:
>
> /^(?:[^s]|s(?!tuff))*$/
>
> That is the whole string is made of either other characters than "s"
> or by "s" not followed by "tuff".
Another option would be
$x =~ /^(?!stuff)(?:.(?!stuff))*$
That is "stuff" is not present at the start of the string nor after
any character.
> You can of course do this trick even is stuff is a regexp, assuming
> it's reasonably complex. Eg.
> $x !~ /\d\d?:\d\d?/;
> is equivalent to
> $x =~ /^(?:\D|\d(?!\d?:\d\d?))*$
In the other style:
$x =~ /^(?!\d\d?:\d\d?)(?:.(?!\d\d?:\d\d?))*$
> Of course you can do this even if the first character of the unwanted
> match may be any character, in that case you just skip the first
> alternative:
>
> $x !~ /(.)\1/; # contains the same character twice in a row
> is equivalent to
> $x =~ /^(?:(.)(?!\1))*$/;
In the other style
$x =~ /^(?!(.)\1)(?:.(?!(.)\2))*$/
Please note that I had to change the backreference in the second
occurance of the unwanted regexp!
HTH, Jenda
===== [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>