2008-12-07 13 views
13

He estado programando en Perl, de vez en cuando, durante años, aunque solo esporádicamente es mi idioma principal. Como a menudo paso meses sin escribir ningún perl, dependo mucho de mi Camel Book para recordarme cómo hacer las cosas. Sin embargo, cuando copio recetas literalmente sin comprensión, esto me molesta. Esta es una de las más irritante: En la página 154 de la tercera edición de camello, no es un ejemplo de "cuerdas de modificación al paso, que dice así:¿En qué actúa el operador de sustitución de Perl?

($lotr = $hobbit) =~ s/Bilbo/Frodo/g; 

Q1) lo que está pasando aquí? ¿En qué consiste exactamente la expresión regular?

Q2) ¿Es necesaria esta sintaxis casi mágica para una operación tan básica como "tomar una cadena de $ a, modificarla con una expresión regular, colocar el resultado en $ b"?

Q3) ¿Cómo hago esta operación usando la variable predeterminada del lazo como la cadena inicial?

Disculpas de antemano a los soñadores de Perl para quienes lo anterior se ve perfectamente natural.

Respuesta

22

Hmmm ... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g es una de las tantas magicas de Perl. Ahora para algunas respuestas.

Q1) $lotr se le asigna el valor contenido en $hobbit. Después de la tarea, podemos olvidarnos de la variable fuente. Tratar ($lotr = $hobbit) ya que es la propia declaración como-si hubiéramos escrito:

$lotr = $hobbit; 
$lotr =~ s/Bilbo/Frodo/g; 

lugar. La expresión regular está operando en $lotr.

Q2) La sintaxis es simplemente una versión de una línea del fragmento dado anteriormente. Piense en ello como "copiar la cadena de $a, copiarlo en $b, y modificar $b con la expresión regular" en lugar de "tomar una cadena de $a, modificarlo con una expresión regular, resultado lugar en $b"

Q3) I ¿Supongo que se refiere al espacio predeterminado de búsqueda de patrones por "variable predeterminada del ciclo"? En ese caso, sólo tiene que utilizar en lugar de $_$hobbit:

while (<>) { 
    chomp; 
    ($lotr = $_) =~ s/Bilbo/Frodo/g; 
    print "\$lotr = [$lotr]\n"; 
    print "\$_ = [$_]\n"; 
} 

Curiosamente, la magia var $_ no se modifica mediante esta operación. Así es como se puede concluir que la asignación ocurre antes de la sustitución de expresiones regulares y que la sustitución no interactúa en el espacio de patrones predeterminado de ninguna manera.

Y para los experimentados programadores de Perl ... No conozco demasiadas personas que se sientan atraídas por alguna sintaxis de Perl, independientemente de cuánto tiempo hayan estado mirándola, por supuesto, señor Schwartz;

+0

Esa respuesta es correcta. Estaba tipeando como se publicó. Por cierto, (la solución) me llevó una búsqueda en Google para encontrarla. – Paul

+0

@ D.Shawley. Jees, compañero. Por lo que dijo anteriormente, ¿por qué $ _ se modificaría? "copie la cadena de $ a ($ _) ... a $ b ($ lotr) y modifique $ b ($ lotr) con la expresión regular, coloque el resultado en $ b ($ lotr)". No hay magia involucrada con $ _ en absoluto. –

+0

Voto por esto, para ser la respuesta aceptada. –

5

Los diferentes idiomas hacen cosas diferentes con el operador de asignación. En algunos, es una declaración, no una expresión, por lo que no se puede combinar en una expresión más grande. En algunos, devuelve el valor asignado, pero solo como un valor (a menudo llamado valor r), no como algo que se puede modificar o asignar (un valor l).Un ejemplo de esto es C, donde puede escribir:

a = b = c; # assign value of c to b and a 

pero no:

++(b = a); # assign value of a to b, then increment b 

y en algunos, el resultado de una asignación es el valor izquierdo asignado a. (En Perl, esto se aplica solo a las asignaciones escalares, las asignaciones de listas son una bestia más compleja). Por lo tanto, puede hacer ++ ($ b = $ a) o ($ b = $ a) = ~ s/a/b/o cualquier otra operación que espera un valor l en la asignación, y primero hará la asignación y luego modificará el valor l asignado.

+0

Gracias, es bueno saber que la sintaxis del ejemplo, aunque no es mágica, es Perl-specific. –

1

Si en la Q2 que quiere decir tomar una subcadena de $ a, es posible encontrar este lenguaje útil:

($b) = $a =~ /(substring-to-match)/; 
$b =~ s/regex-on-susbtring/result-string/; 

hacen también en cuenta que $ ay $ b no son variables normales en Perl, ya que tienen reglas especiales de alcance relacionadas con la función de ordenación. Ver 'perldoc perlvar' para más detalles.

Cuestiones relacionadas