2012-04-18 11 views
8

En un Perl SO answer, un cartel utiliza este código para que coincida con las cadenas vacías:

$userword =~ /^$/; #start of string, followed immediately by end of string 

A lo que brian d foy comentó:

Realmente no se puede decir que debido a que coincide con uno en particular no -cuerda vacía.

Pregunta: ¿Qué cadena no vacía coincide con esta? ¿Es una cadena que consiste en "\r" solamente?

+1

Este es el mismo error es http://stackoverflow.com/q/10200057/8817 haciendo, también. :) –

Respuesta

7

Vamos a comprobar la documentación, ¿por qué no? Cita perlre,

$: Coincide con el final de la línea (o antes del salto de línea al final)

Dada

\z: Que sólo al final de la cadena

Eso significa /^$/ es equivalente a /^\n?\z/.

$ perl -E'$_ = ""; say /^$/ ||0, /^\n?\z/ ||0, /^\z/ ||0;' 
111 

$ perl -E'$_ = "\n"; say /^$/ ||0, /^\n?\z/ ||0, /^\z/ ||0;' 
110 

Tenga en cuenta que los cambios /m lo ^ y $ partido. Debajo de /m, ^ coincide al comienzo de cualquier "línea", y $ coincide antes de cualquier nueva línea y al final de la cadena.

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /^/g' 
matched at 0 

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /$/g' 
matched at 7 
matched at 8 

Y el uso/m:

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /^/mg' 
matched at 0 
matched at 4 <-- new 

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /$/mg' 
matched at 3 <-- new 
matched at 7 
matched at 8 

\A, \Z y \z aren' t afectados por /m:

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /\A/g' 
matched at 0 

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /\z/g' 
matched at 8 

$ perl -E'$_ = "abc\ndef\n"; say "matched at $-[0]" while /\Z/g' 
matched at 7 
matched at 8 
9
use strict; 
use warnings; 

use Test::More; 

ok("\n" =~ /^$/); 
ok("\n" =~ /^\z/); 
ok("\n" =~ /^\A\z/); # Better as per brian d. foy's suggestion 

done_testing; 

Si desea probar si una cadena está vacía, utilice /^\z/ o ver si length de $str es cero (que es lo que prefiero).

Salida:

ok 1 
not ok 2 
not ok 3
+4

Si desea probar una cadena vacía usando una expresión regular, use '\ A' también. El^no garantiza que nada esté delante de él. –

+0

@briandfoy En el caso de '^', estoy seguro siempre que no use el modificador 'm'. Por otro lado, '$' no necesita ayuda desagradable de ningún modificador externo para hacerme tropezar ;-) –

+1

No estás seguro, porque Perl ahora tiene indicadores de regex predeterminados. Sin embargo, ¿por qué usar algo exacto cuando puede ser exacto sin excepción? –

3

La expresión regular /^$/ coincide con la cadena no vacía "\n".

De forma predeterminada, la coincidencia de expresiones regulares de Perl asume que la cadena contiene una sola "línea" de texto.

^ coincide al principio de la línea; en ausencia de un modificador /m, este es el mismo que el comienzo de la cadena.

$ partidos ya sea el final de la línea, o antes de una nueva línea al final (que es lo que hace /^$/ partido de la cadena no vacía "\n").

Citando perldoc perlre:

Por defecto, el "^" personaje está garantizada para que coincida con sólo el principio de la cadena, el carácter "$" sólo el final (o antes de la nueva línea al final), y Perl realiza ciertas optimizaciones con la suposición de que la cadena contiene solo una línea. Las nuevas líneas integradas no se combinarán con "^" o "$". Sin embargo, puede tratar una cadena como un búfer multilínea, de modo que "^" coincidirá después de cualquier nueva línea dentro de la cadena (excepto si la nueva línea es el último carácter en la cadena), y " $ "coincidirá antes de cualquier nueva línea. A un costo de un poco más por encima, puede hacer esto utilizando el modificador/m en el operador de coincidencia de patrón.

+0

Si hay una buena razón para la votación negativa, me gustaría escucharla. –

+0

@ SinanÜnür: Los votos a la baja son por supuesto anónimos, por lo que no podemos estar seguros de quién me votó negativamente. En cualquier caso, estaba más preocupado de que pudiera haber algún problema con mi respuesta. (Encontré a la mayoría de los otros demasiado indirectos, yendo en una tangente antes de responder la pregunta). No hay problema. –

+0

Renuncie al equilibrio si incluyó exactamente WHAT $ y^mean (sé que puedo ver las definiciones de abogacía exactas en perldoc, esto es simplemente una pista sobre cómo mejorar la respuesta aún más) – DVK

1

Guión:

my $str = "\n"; 

my $test1 = ($str =~ /^$/) ? 1 : 0; 
my $test2 = ($str =~ /\A\z/) ? 1 : 0; 

print "$test1, $test2\n"; 

Salida:

1, 0 
+0

¿Cómo es esto diferente de la respuesta de Sinan? – DVK

+0

@DVK - Después ** de ** editar y agregar '\ A' a su respuesta, no hay diferencia. –

+0

@stackoverflow Tenga en cuenta ** No ** edité mi respuesta para incluir '\ A'. –

Cuestiones relacionadas