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>


Reply via email to