2010-10-21 8 views
10

Si me quedo

"Year 2010" =~ /([0-4]*)/; 
print $1; 

me sale cadena vacía. Pero

"Year 2010" =~ /([0-4]+)/; 
print $1; 

salidas "2010". ¿Por qué?

+0

Lo que es extraño es que '/ \ s ([0-4] *) /' no tiene el mismo comportamiento de acceso directo. No dice "He igualado la cadena de longitud cero al final del espacio, aquí tienes". – Axeman

+0

@Axeman, eso es porque '*' es codicioso. Los dígitos están ahí, entonces los agarra. Si coincide con ''El año 2010'',' $ 1' sería la cadena de longitud cero que sigue al primer espacio. – cjm

Respuesta

19

Obtiene una coincidencia vacía justo al comienzo de la cadena "Año 2010" para el primer formulario porque el * coincidirá inmediatamente con 0 dígitos. El formulario + tendrá que esperar hasta que vea al menos un dígito antes de que coincida.

Es de suponer que si se puede ir a través de todos los los partidos de la primera forma, es muy probable encontrará 2010 ... pero probablemente sólo después de que encuentre otro partido vacío antes de la 'e', ​​a continuación, antes de la 'a' etc.

+0

¡Genial, gracias! – alexanderkuk

+0

Kleene star-generated superset contiene también cadena vacía, así que sí, coincidirá cadena vacía antes de Y, e, a, r, espacio en blanco, y luego encontrará 2010. –

5

La primera coincide con la cadena de longitud cero al principio (antes de Y) y la devuelve. El segundo busca uno o más dígitos y espera hasta que encuentre 2010.

6

La primera expresión regular coincide satisfactoriamente con cero dígitos al comienzo de la cadena, lo que da como resultado la captura de la cadena vacía.

La segunda expresión regular no coincide con el inicio de la cadena, pero coincide cuando alcanza 2010.

5

también se puede utilizar YAPE::Regex::Explain para la explicación de una expresión regular como

use YAPE::Regex::Explain; 

print YAPE::Regex::Explain->new('([0-4]*)')->explain(); 
print YAPE::Regex::Explain->new('([0-4]+)')->explain(); 

salida:

The regular expression: 
(?-imsx:([0-4]*)) 
matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    [0-4]*     any character of: '0' to '4' (0 or more 
          times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 

The regular expression: 
(?-imsx:([0-4]+)) 
matches as follows: 

NODE      EXPLANATION 
---------------------------------------------------------------------- 
(?-imsx:     group, but do not capture (case-sensitive) 
         (with^and $ matching normally) (with . not 
         matching \n) (matching whitespace and # 
         normally): 
---------------------------------------------------------------------- 
    (      group and capture to \1: 
---------------------------------------------------------------------- 
    [0-4]+     any character of: '0' to '4' (1 or more 
          times (matching the most amount 
          possible)) 
---------------------------------------------------------------------- 
)      end of \1 
---------------------------------------------------------------------- 
)      end of grouping 
---------------------------------------------------------------------- 
1

el símbolo de la estrella intenta hacer coincidir básicamente a 0 o más símbolos en conjunto dado (en teoría, el conjunto {x, y} * consiste de cadena vacía y todas las posibles secuencias finitas hechas de xey), y por lo tanto, coincidirá exactamente con cero caracteres (cadena vacía) al comienzo de la cadena, cero caracteres después del primer carácter, cero caracteres después del segundo carácter, etc. Entonces finalmente encontrará 2 y coincidirá todo 2010.

El símbolo más coincide con uno o más caracteres del conjunto dado ({x, y} + consiste en todas las secuencias finitas posibles hechas de x y y, sin la cadena vacía , a diferencia de {x, y} *). Entonces, el primer personaje coincidente es 2, luego el siguiente - 0 se marca, luego 1, luego otro 0, y luego la oración termina, por lo que el grupo encontrado se ve como '2010'.

Es un comportamiento estándar para las expresiones regulares, definidas en la teoría del lenguaje formal. Yo recomiendo aprender un poco sobre la teoría de las expresiones regulares, no puede hacer daño, pero puede ayudar :)

0

Para hacer su primer partido RE, utilice el ancla '$':

"Year 2010" =~ /([0-4]*)$/; 
print $1; 
1

Tenemos esto como una pregunta trampa en Learning Perl. Cualquier expresión regular que pueda coincidir con cero caracteres que no coincidan al principio de la cadena coincidirá con cero caracteres.

El motor Perl regex coincide con la coincidencia más larga del extremo izquierdo, y la parte más a la izquierda está primero.Sin embargo, no todos los motores regex funcionan así. Si desea todos los detalles técnicos, lea Mastering Regular Expressions, que explica cómo funcionan los motores de expresiones regulares y encuentra coincidencias.

Cuestiones relacionadas