test - regex perl online
Regex negativa para coincidencia de patrĂ³n de cuerda Perl (5)
¿Qué pasa con el uso de dos expresiones regulares (o tres)? Esto hace que tus intenciones sean más claras e incluso pueden mejorar tu rendimiento:
if ($string =~ /^(Clinton|Reagan)/i && $string !~ /Bush/i) { ... }
if (($string =~ /^Clinton/i || $string =~ /^Reagan/i)
&& $string !~ /Bush/i) {
print "$string/n"
}
Tengo esta expresión regular:
if($string =~ m/^(Clinton|[^Bush]|Reagan)/i)
{print "$string/n"};
Quiero unirme a Clinton y Reagan, pero no a Bush.
No funciona.
Si mi comprensión es correcta, entonces quiere hacer coincidir cualquier línea que tenga Clinton y Reagan, en cualquier orden, pero no con Bush. Según lo sugerido por Stuck, aquí hay una versión con aserciones anticipadas:
#!/usr/bin/perl
use strict;
use warnings;
my $regex = qr/
(?=.*clinton)
(?!.*bush)
.*reagan
/ix;
while (<DATA>) {
chomp;
next unless (/$regex/);
print $_, "/n";
}
__DATA__
shouldn''t match - reagan came first, then clinton, finally bush
first match - first two: reagan and clinton
second match - first two reverse: clinton and reagan
shouldn''t match - last two: clinton and bush
shouldn''t match - reverse: bush and clinton
shouldn''t match - and then came obama, along comes mary
shouldn''t match - to clinton with perl
Resultados
first match - first two: reagan and clinton
second match - first two reverse: clinton and reagan
según lo deseado, coincide con cualquier línea que tenga a Reagan y Clinton en cualquier orden.
Puede intentar leer cómo funcionan las aserciones anticipadas con ejemplos en http://www252.pair.com/comdog/mastering_perl/Chapters/02.advanced_regular_expressions.html
son muy sabrosos :)
Su expresión regular dice lo siguiente:
/^ - if the line starts with
( - start a capture group
Clinton| - "Clinton"
| - or
[^Bush] - Any single character except "B", "u", "s" or "h"
| - or
Reagan) - "Reagan". End capture group.
/i - Make matches case-insensitive
Entonces, en otras palabras, tu parte media de la expresión regular te está jodiendo. Como es un tipo de grupo "catch-all", permitirá cualquier línea que no comience con ninguna de las letras mayúsculas o minúsculas en "Bush". Por ejemplo, estas líneas coincidirían con su expresión regular:
Our president, George Bush
In the news today, pigs can fly
012-3123 33
O haces una anticipación negativa, como se sugirió anteriormente, o simplemente haces dos expresiones regulares:
if( ($string =~ m/^(Clinton|Reagan)/i) and
($string !~ m/^Bush/i) ) {
print "$string/n";
}
Como ha señalado mirod en los comentarios, el segundo control es bastante innecesario cuando se usa el cursor ( ^
) para hacer coincidir solo el comienzo de las líneas, ya que las líneas que comienzan con "Clinton" o "Reagan" nunca podrían comenzar con "Bush".
Sin embargo, sería válido sin los caretas.
Su expresión regular no funciona porque [] define una clase de caracteres, pero lo que quiere es una búsqueda anticipada:
(?=) - 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)
Así que intente: (?! Bush)
Texto de ejemplo:
Clinton dijo
Bush usó lápices de colores
Reagan olvidó
Solo omitiendo un partido de Bush:
$ perl -ne ''print if /^(Clinton|Reagan)/'' textfile
Clinton said
Reagan forgot
O si realmente desea especificar:
$ perl -ne ''print if /^(?!Bush)(Clinton|Reagan)/'' textfile
Clinton said
Reagan forgot