2012-04-24 22 views
6

El Ruby (1.9.3) la documentación parece implicar que la exploración es equivalente a = ~ excepto que scanrubí regex scan frente = ~

  1. devuelve varias coincidencias, mientras = ~ rendimientos sólo la primera aparición, y
  2. exploración devuelve los datos de coincidencia, mientras que = ~ devuelve el índice.

Sin embargo, en el siguiente ejemplo, los dos métodos parecen devolver resultados diferentes para la misma cadena y expresión. ¿Porqué es eso?

1.9.3p0 :002 > str = "Perl and Python - the two languages" 
=> "Perl and Python - the two languages" 
1.9.3p0 :008 > exp = /P(erl|ython)/ 
=> /P(erl|ython)/ 
1.9.3p0 :009 > str =~ exp 
=> 0 
1.9.3p0 :010 > str.scan exp 
=> [["erl"], ["ython"]] 

Si el índice del primer partido es 0, no hay que escanear retorno "Perl" y "Python" en lugar de "ERL" y "pitón"?

Gracias

Respuesta

12

Cuando se le asigne una expresión regular y sin grupos de captura, scan volverán una matriz de cadenas, donde cada cadena representa un partido de la expresión regular. Si usa scan(/P(?:erl|ython)/) (que es lo mismo que su expresión regular, excepto sin capturar grupos), obtendrá ["Perl", "Python"], que es lo que espera.

Sin embargo cuando se le da una expresión regular con grupos de captura, scan devolverá una matriz de matrices, donde cada subarreglo contiene las capturas de una coincidencia dada. Así que si tiene, por ejemplo, la expresión regular (\w*):(\w*), obtendrá una matriz de matrices donde cada subarreglo contiene dos cadenas: la parte anterior al colon y la parte posterior al colon. Y en su ejemplo, cada subarreglo contiene una cadena: la parte coincide con (erl|ython).

+0

Gracias, ¿entonces el escaneo no es estrictamente equivalente a = ~, cuando hay grupos involucrados? – Anand

+2

@Anand Dado que el análisis arroja algo completamente diferente de = ~, no creo que sea exacto decir que son equivalentes. El primer resultado devuelto por el escaneo será una subcadena que comienza en el índice 'str = ~ exp' si y solo si' exp' no contiene grupos de captura. Además de eso, también puedes decir que el primer resultado será equivalente a 'Regexp.last_match.string' obtener después de ejecutar' str = ~ exp' si el no contiene grupos de captura y 'Regexp.last_match.captures' si contiene grupos de captura. – sepp2k

+0

Me alegra ver este tipo de publicación de la que realmente puedes aprender. – texasbruce