cómo incluir grep en una expresión regular en perl
Frecuentes
Visto 453 veces
0
así que actualmente estoy atascado en este problema: 1. Declaro una lista constante, digamos LISTA 2. Quiero leer un archivo, lo cual hago línea por línea en un ciclo while, y si la línea tiene una palabra clave de LISTA, imprimo la línea, o algo así con ella.
esto es lo que tengo actualmente:
use constant LIST => ('keyword1', 'keyword2', 'keyword3');
sub main{
unless(open(MYFILE, $file_read)){die "Error\n"};
while(<MYFILE>){
my $line = $_;
chomp($line);
if($line =~ m//){#here is where i'm stuck, i want is if $line has either of the keywords
print $line;
}
}
}
¿Qué debo hacer en esa declaración if para que coincida con lo que quiero que haga el programa? y puedo hacerlo sin tener el $line
variable y simplemente usando $_
? solo usé $line porque pensé que grep colocaría automáticamente las constantes en LIST en $_
. ¡Gracias!
1 Respuestas
2
La forma más fácil es definir un expresión regular citada como su constante en lugar de una lista:
use strict;
use warnings;
use autodie; # Will kill program on bad opens, closes, and writes
use feature qw(say); # Better than "print" in most situations
use constant {
LIST => qr/keyword1|keyword2|keyword3/, # Now a regular expression.
FILE_READ => 'file.txt', # You're defining constants, make this one too.
};
open my $read_fh, "<", FILE_READ; # Use scalars for file handles
# This isn't Java. You don't have to define "main" subroutine
while ( my $line = <$read_fh> ) {
chomp $line;
if ( $line =~ LIST ) { #Now I can use the constant as a regex
say $line;
}
}
close $read_fh;
Por cierto, si no usas Autodie, la forma estándar de abrir un archivo y fallar si no se abre es usar el or
sintaxis:
open my $fh, "<", $file_name or die qq(Can't open file "$file_name": $!);
Si tiene que usar una lista como una constante, entonces puede usar join
para hacer la expresión regular:
use constant LIST => qw( keyword1 keyword2 keyword3 );
...
my $regex = join "|", map LIST;
while ( my $line = <$file_fh> ) {
chomp $line;
if ( $line =~ /$regex/ ) {
say $line;
}
}
El join
toma una lista (en este caso, una lista constante) y separa cada miembro por la cadena o el carácter que le asigna. Espero que sus palabras clave no contengan caracteres especiales de expresiones regulares. De lo contrario, necesita cotización inicial esos caracteres especiales.
Apéndice
mi $regex = unir '|' => mapa +quotemeta, LISTA; – Zaid
Gracias Zaid. yo no sabía sobre el quotemeta
mando antes. Había estado probando varias cosas con \Q
y \E
, pero empezó a ser demasiado complejo.
Otra forma de hacer lo que hizo Zaid:
my @list = map { quotemeta } LIST;
my $regex = join "|", @list;
El mapa es un poco difícil de entender para los principiantes. map
toma cada elemento en LIST
y ejecuta el cita orden en su contra. esto vuelve -- que asigno a @list
.
Imagine:
use constant LIST => qw( periods.are special.characters in.regular.expressions );
Cuando corro:
my @list = map { quotemeta } LIST;
Esto devuelve la lista:
my @list = ( "periods\.are", "special\.characters", "in\.regular\.expressions" );
Ahora, los puntos son puntos literales en lugar de caracteres especiales en la expresión regular. Cuando corro:
my $regex = join "|", @list;
Yo obtengo:
$regex = "periods\.are|special\.characters|in\.regular\.expressions";
Y esa es una expresión regular válida.
Respondido el 20 de junio de 20 a las 10:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas regex perl grep or haz tu propia pregunta.
@Zaid No sabía sobre el
quotemeta
mando antes. Eso funciona muy bien. - David W.