2011-07-23 17 views
60

Sé que puedo escribir una declaración de caso Ruby para verificar una coincidencia con una expresión regular. Sin embargo, me gustaría utilizar los datos de coincidencia en mi declaración de devolución. Algo como este semi-pseudocódigo:¿Cómo escribir una declaración de cambio de Ruby (caso ... cuándo) con expresiones regulares y referencias retrospectivas?

foo = "10/10/2011" 

case foo 
    when /^([0-9][0-9])/ 
     print "the month is #{match[1]}" 
    else 
     print "something else" 
end 

¿Cómo puedo lograr eso?

Gracias!


Sólo una nota: entiendo que no me ha consumido alguna vez una sentencia switch para un caso sencillo que el anterior, pero eso es sólo un ejemplo. En realidad, lo que estoy tratando de lograr es la coincidencia de muchas expresiones regulares potenciales para una fecha que se puede escribir de varias maneras, y luego analizarla con la clase Date de Ruby en consecuencia.

+0

Ruby's Date.parse entiende muchos formatos de fecha. ¿Lo has probado? – raine

+0

Aunque no responde a esta pregunta, es posible que desee ver la joya crónica ... – DGM

Respuesta

108

Las referencias a la última expresión regular se encontraron grupos se almacenan siempre en pseudo variables$1 a $9:

case foo 
when /^([0-9][0-9])/ 
    print "the month is #{$1}" 
else 
    print "something else" 
end 

También puede utilizar la variable de seudo $LAST_MATCH_INFO para llegar a todo el MatchData objeto. Esto puede ser útil cuando se utilizan capturas con nombre:

case foo 
when /^(?<number>[0-9][0-9])/ 
    print "the month is #{$LAST_MATCH_INFO['number']}" 
else 
    print "something else" 
end 
+0

... simplemente bien hecho y +1 :) – apneadiving

+0

Todah, Yossi - Bidiuk ma she hipasti. –

+0

@Yossi ¿Tiene alguna fuente de información sobre la seguridad de las hebras? Acabo de hacer un experimento en ruby ​​1.8.7 que parece indicar que es seguro para subprocesos. (Subproceso que coincide con una expresión regular cada segundo - comprobando si hay coincidencias locales) – Joel

4

Aquí es un enfoque alternativo que se obtiene el mismo resultado, pero no utiliza un interruptor. Si coloca sus expresiones regulares en una matriz, se podría hacer algo como esto:

res = [ /pat1/, /pat2/, ... ] 
m = nil 
res.find { |re| m = foo.match(re) } 
# Do what you will with `m` now. 

Declarar m fuera del bloque permite que siendo accesibles dentro de find se hace con el bloque y find se detendrá tan pronto como el bloque devuelve un valor verdadero para que obtenga el mismo comportamiento de acceso directo que un interruptor le da. Esto le da el total de MatchData si lo necesita (quizás desee usar grupos de captura con nombre en sus expresiones regulares) y separa sus expresiones regulares de su lógica de búsqueda (que puede o no dar un código más claro), incluso podría cargar sus expresiones regulares de un archivo de configuración o elegir qué conjunto de ellos quería en el tiempo de ejecución.

+0

También estaba pensando en la seguridad de subprocesos usando el enfoque de 'caso'. Tal vez quiera usar el enfoque de mu en un escenario enhebrado, en lugar de una variable global con el enfoque de caso (?) – Casper

Cuestiones relacionadas