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>