48 votes

Regex négative pour la correspondance du modèle de chaîne Perl

J'ai cette regex :

 if($string =~ m/^(Clinton|[^Bush]|Reagan)/i)
  {print "$string\n"};

Je veux rivaliser avec Clinton et Reagan, mais pas avec Bush.

Ça ne fonctionne pas.

147voto

Stuck Points 2206

Votre regex ne fonctionne pas car [] définit une classe de caractères, mais ce que vous voulez, c'est une prévision :

 (?=) - Positive look ahead assertion foo(?=bar) matches foo when followed by bar
(?!) - Negative look ahead assertion foo(?!bar) matches foo when not followed by bar
(?<=) - Positive look behind assertion (?<=foo)bar matches bar when preceded by foo
(?<!) - Negative look behind assertion (?<!foo)bar matches bar when NOT preceded by foo
(?>) - Once-only subpatterns (?>\d+)bar Performance enhancing when bar not present
(?(x)) - Conditional subpatterns
(?(3)foo|fu)bar - Matches foo if 3rd subpattern has matched, fu if not
(?#) - Comment (?# Pattern does x y or z)

Alors essaie : (?!bush)

33voto

Demosthenex Points 1847

Exemple de texte :

Clinton a dit Bush a utilisé des crayons Reagan a oublié

En omettant juste un match de Bush :

 $ perl -ne 'print if /^(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot

Ou si vous voulez vraiment préciser :

 $ perl -ne 'print if /^(?!Bush)(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot

3voto

mob Points 61524

Quel est le problème avec l'utilisation de deux expressions régulières (ou trois) ? Cela rend vos intentions plus claires et peut même améliorer vos performances :

 if ($string =~ /^(Clinton|Reagan)/i && $string !~ /Bush/i) { ... }

if (($string =~ /^Clinton/i || $string =~ /^Reagan/i)
        && $string !~ /Bush/i) {
    print "$string\n"
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X