2011-11-15 20 views
8

Estoy tratando de hacer un subcadena simple en Ruby.subcadena Ruby sub sin regex referencias atrás

El segundo argumento para sub() es una larga porción de JavaScript minificado que tiene expresiones regulares contenidas en él. Las referencias anteriores en la expresión regular en esta cadena parecen estar afectando el resultado de sub, porque la cadena reemplazada (es decir, el primer argumento) está apareciendo en la cadena de salida.

Ejemplo:

input = "string <!--tooreplace--> is here" 
output = input.sub("<!--tooreplace-->", "\&") 

Quiero que la salida sea:

"string \& is here" 
No

:

"string & is here" 

escapar o si la expresión regular

"string <!--tooreplace--> is here" 

Básicamente, quiero una forma de hacer un subcadena que no tenga consecuencias de expresiones regulares, solo un simple reemplazo de cadena.

+0

¿Puedes crear un pequeño ejemplo que demuestre el problema? –

+0

Ejemplo de código agregado. –

Respuesta

2

Use comillas simples y escapar de la barra invertida:

output = input.sub("<!--tooreplace-->", '\\\&') #=> "string \\& is here" 
6

para evitar tener que encontrar la manera de escapar de la cadena de reemplazo, utilice Regex.escape. Es útil cuando los reemplazos son complicados, o lidiar con eso es un dolor innecesario. Un pequeño ayudante en String también es bueno.

input.sub("<!--toreplace-->", Regexp.escape('\&')) 
+2

Eso soluciona el ejemplo, pero parece causar problemas en otros lugares. Por ejemplo, si cambia el 2do arg a '\ &, O =/\ s * ([\ s \ + \ ~>]) \ s */g', entonces el resultado se ve como 'cadena \ &, O =/\ s \ * \ (\ [\ s \\ ~> \] \) \ s \ */g está aquí 'con un montón de cosas extra escapadas. –

3

También puede utilizar la notación de bloque para que sea más simple (en contraposición a Regexp.escape):

=> puts input.sub("<!--tooreplace-->") {'\&'} 
string \& is here 
+0

Increíblemente útil, especialmente porque se aplica a otros usos (por ejemplo, leer un archivo y usar el contenido del archivo como la cadena de reemplazo) en el que escaparse simplemente no es una opción. –

0

Bueno, ya '\\&' (es decir, \ seguido por &) se interpreta como una declaración especial de expresiones regulares, es lógico pensar que necesita escapar de la barra diagonal inversa. De hecho, esto funciona:

>> puts 'abc'.sub 'b', '\\\\&' 
a\&c 

Tenga en cuenta que \\\\& representa la cadena literal \\&.

Cuestiones relacionadas