2012-07-13 16 views
6

Tengo un script de Perl que lee la búsqueda de expresiones regulares y reemplaza los valores de un archivo INI.Perl: pasar la búsqueda de expresiones regulares y reemplazar utilizando las variables

Esto funciona bien hasta que intento usar las variables de captura ($ 1 o \ 1). Estos se reemplazan literalmente con $ 1 o \ 1.

¿Alguna idea de cómo puedo hacer que funcione esta funcionalidad de captura pasando bits de expresiones regulares a través de variables? Ejemplo de código (no usar un archivo ini) ...

$test = "word1 word2 servername summary message"; 

$search = q((\S+)\s+(summary message)); 
$replace = q(GENERIC $4); 

$test =~ s/$search/$replace/; 
print $test; 

Esto se traduce en ...

word1 word2 GENERIC $4 

NO

word1 word2 GENERIC summary message 

gracias

+0

su patrón de búsqueda no tendrá éxito, hay **!: ** al final del patrón de búsqueda, pero no en la cadena. – tuxuday

+0

perdón error de mi parte,!: Debería haber sido eliminado del ejemplo – andyml73

Respuesta

6

Uso doble evaluación:

$search = q((\S+)\s+(summary message)); 
$replace = '"GENERIC $1"'; 

$test =~ s/$search/$replace/ee; 

Tenga en cuenta las comillas dobles en $replace y ee al final de s///.

+0

que hace el truco, aplausos – andyml73

-1

Use \ 4, no $ 4.

$ 4 no tiene un significado especial en q(), ni lo reconoce el motor de RE.

\ 4 tiene un significado especial para el motor de RE.

+0

Arkadiy, eso no ayudará, por supuesto. Necesita un paso de evaluación adicional. –

+0

Oh crep - Pensé que el perl tiene interpolación variable y luego aplica la sintaxis RE - Supongo que estaba equivocado y los valores de las variables se tratan como literales. Gracias por mencionarlo. – Arkadiy

0

intentar someter la expresión regular-sub a eval, se advirtió que la sustitución está viniendo de archivo externo

eval "$test =~ s/$search/$replace/"; 
0

Otra solución interesante sería utilizar look-aheads (?=PATTERN)

Su ejemplo sería entonces sólo reemplazar lo necesita ser reemplazado:

$test = "word1 word2 servername summary message"; 

# repl. only ↓THIS↓ 
$search = qr/\S+\s+(?=summary message)/; 
$replace = q(GENERIC); 

$test =~ s/$search/$replace/; 
print $test; 
+0

Me gusta, esto puede ser más elegante, gracias – andyml73

0

Si te gusta la solución de Amon, supongo que el "genérico $ 1" no es de configuración (especia lly la parte '$ 1' en ella). En ese caso, creo que hay una solución aún más simple, sin el uso de look-aheads:

$test = "word1 word2 servername summary message"; 
$search = qr/\S+\s+(summary message)/; 
$replace = 'GENERIC'; 
$test =~ s/$search/$replace $1/; 

Aunque no hay nada realmente mal por supuesto (= PATRÓN?).

Cuestiones relacionadas