2011-02-05 23 views
10

Estoy tratando de almacenar una expresión regular s///g como variable (sin mucha suerte).Cómo guardar una expresión regular de sustitución (buscar/reemplazar) en una variable, similar a qr //

Aquí hay un ejemplo que usa una coincidencia normal para mostrar lo que pretendo hacer.

my %file_structure = (
    header => qr/just another/, 
    table => qr/perl beginner/, 
) 

Ahora puedo llamar a esto usando $line =~ $file_structure{'header'} y volverá undef, o true si el patrón coincide.

Sin embargo, me gustaría decir $line =~ $file_structure{'foo'} donde $file_structure{'foo'} contiene algo así como s/beginner/hacker/g.

Respuesta

10

Debe almacenar las 2 partes por separado:

my %file_structure = (
    foo => {pat => qr/beginner/, repl => 'hacker'}, 
); 

my $line = 'just another perl beginner'; 
$line =~ s/$file_structure{foo}{pat}/$file_structure{foo}{repl}/; 
print "$line\n"; 

que sería mucho más seguro que recurrir a un mal "EXPR eval":

my %file_structure = (
    foo => 's/beginner/hacker/', 
); 

my $line = 'just another perl beginner'; 
eval "\$line =~ $file_structure{foo}"; 
print "$line\n"; 
+0

La excepción es si usted necesita para representar banderas como '/ e' o '/ G' en alguna parte, porque los que no se puede representar en los LHS como '/ x' o'/i' puede. Debe usar las mismas banderas de sustitución cada vez, o usar una cadena de tiempo de ejecución 'eval' cuando no pueda. – tchrist

+0

Tiene que utilizar este método http://stackoverflow.com/questions/392643/how-to-use-a-variable-in-the-replacement-side-of-the-perl-substitution-operator si desea incluye una expresión capturada en el lado derecho. Es más seguro, de todos modos, y más general – jjmerelo

9

A medida que han encontrado, no hay manera para almacenar directamente una expresión regular de sustitución como puede una coincidencia de expresiones regulares (con qr//). Puedes romper las partes y recombinarlas como muestra tadmc. Otra forma de hacer esto es para almacenar la sustitución de un subprograma:

my %file_structure = (
    foo_uses_default => sub {s/foo/bar/}, 
    foo_takes_arg => sub {$_[0] =~ s/foo/bar/}, 
    foo_does_either => sub {(@_ ? $_[0] : $_) =~ s/foo/bar/}, 
); 

$file_structure{foo_uses_default}() for ...; 
$file_structure{foo_uses_arg}($_) for ...; 
+2

También podría hacer 'map $ file_structure {foo_whatever}, ...' y creo que cualquiera de esas tres versiones sería adecuada para que una expresión pase en ese caso. –

Cuestiones relacionadas