2010-08-06 34 views
36

Digamos que tengo una cadena arbitraria comoCrear una expresión regular entre mayúsculas y minúsculas de una cadena en Ruby

`A man + a plan * a canal : Panama!` 

y quiero hacer una búsqueda de expresiones regulares para las cadenas que son los mismos que no sea el caso. Es decir, esta expresión regular debe coincidir con la cadena

`a man + A PLAN * a canal : PaNaMa!` 

tomo el mejor enfoque consiste en barra invertida-escapar de cada personaje con un significado especial en las expresiones regulares de Ruby, y luego hago Regexp.new con esta cadena y Regexp::IGNORECASE como argumentos . ¿Está bien? ¿Hay una expresión regular probada y verdadera para convertir cadenas arbitrarias en literal expresiones regulares?

Por cierto, en última instancia, quiero usar esta expresión regular para hacer una consulta de MongoDB arbitrariamente insensible a mayúsculas y minúsculas. Entonces, si hay otra manera en que podría estar haciendo eso, háganmelo saber.

Respuesta

40

Puede usar Regexp.escape para escapar de todos los caracteres de la cadena que de otro modo serían manejados especialmente por el motor de expresiones regulares.

Regexp.new(Regexp.escape("A man + a plan * a canal : Panama!"), Regexp::IGNORECASE) 

o

Regexp.new(Regexp.escape("A man + a plan * a canal : Panama!"), "i") 
+0

¡Gracias, eso era justo lo que estaba buscando! (Aunque en cuanto a MongoDB, me di cuenta de que si hago este tipo de búsqueda a menudo, realmente debería almacenar una versión descifrada de la cadena por motivos de rendimiento.) –

22

Si conoce la expresión regular que ya desea, puede añadir "i" después de la expresión (por ejemplo /the center cannot hold it is too late/i) para que sea case insensitive.

+3

Correcto, pero esa no es la pregunta que estoy formulando. Tengo una cadena arbitraria (de entrada del usuario), no una expresión regular. Si el usuario introduce 'a + b', por ejemplo, quiero poder encontrar' A + b', 'a + B', o' A + B', no 'aaaaab'. –

6

Un poco más sintáctico-azucarada manera de hacer esto es utilizar la notación %r para los literales Regexp:

input_str = "A man + a plan * a canal : Panama!" 
%r(#{Regexp.escape(input_str)})i 

Por supuesto se trata de una cuestión de preferencia personal.

37

Las expresiones regulares de Ruby pueden interpolar expresiones de la misma manera que las cadenas, usando la notación #{}. Sin embargo, tienes que escapar de los caracteres especiales de expresiones regulares. Por ejemplo:

input_str = "A man + a plan * a canal : Panama!" 
/#{Regexp.escape input_str}/i 
+2

Esta es una gran respuesta: se lee mucho mejor que la respuesta más votada y me parece más bien a Ruby. Espero que los demás voten por alto esto también .. –

Cuestiones relacionadas