2011-04-14 16 views
14

Quiero hacer una búsqueda de cadenas dentro de una cadena. Simplemente diciendo MySTR.search(Needle).Cómo escaparse correctamente de los caracteres en la expresión regular

El problema se produce cuando esta cadena needle contiene caracteres especiales de expresiones regulares como *, + y así sucesivamente. Falla con el error invalid quantifier.

He navegado por la web y he descubierto que la cadena se puede escapar con \Q some string \E.

Sin embargo, esto no siempre produce el comportamiento deseado. Por ejemplo:

var sNeedle = '*Stars!*'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

El resultado es -1. DE ACUERDO.

var sNeedle = '**Stars!**'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

El resultado es "cuantificador no válido". Esto sucede porque 2 o más caracteres especiales se 'tocan' entre sí, porque:

var sNeedle = '*Dont touch me*Stars!*Dont touch me*'; 
var sMySTR = 'The contents of this string have no importance'; 
sMySTR.search('\Q' + sNeedle + '\E'); 

Funcionará correctamente.

Sé que podría hacer una función escapeAllBadChars(sInStr) y simplemente agregar barras diagonales dobles antes de cada posible carácter especial de expresiones regulares, pero me pregunto si hay una forma más sencilla de hacerlo.

+3

\ Q ... \ E trabaja en Perl, no está seguro acerca en cualquier otro lugar sin embargo. –

+1

Creo que las estrellas en su tercer ejemplo no están haciendo lo que usted piensa. No se interpretan como caracteres literales *, sino como cuantificadores para los personajes que los precedieron. –

+0

@Matthew, en Java funciona igual que en Perl (no estoy seguro acerca de otros lenguajes). –

Respuesta

30

\Q...\E no funciona en JavaScript (al menos, no se escapen nada ...) como se puede ver:

var s = "*"; 
print(s.search(/\Q*\E/)); 
print(s.search(/\*/)); 

produce:

-1 
0 

como se puede ver en Ideone.

Los siguientes caracteres tienen que ser escapado:

  • (
  • )
  • [
  • {
  • *
  • +
  • .
  • $
  • ^
  • \
  • |
  • ?

Por lo tanto, algo como esto haría:

function quote(regex) { 
    return regex.replace(/([()[{*+.$^\\|?])/g, '\\$1'); 
} 

No, ] y } no necesitan escaparse: no tienen ningún significado especial, solo sus contrapartes de apertura.

Tenga en cuenta que al utilizar una expresión regular literal, /.../, también debe escapar del carácter /. Sin embargo, / no es un metacaracidor de expresiones regulares: al usarlo en un objeto RegExp, no necesita un escape.

+1

aplastante respuesta! –

+0

personaje/necesita ser escapado también – lopata

+0

@TheoZ, no llamaría a '/' de regex meta char. Solo necesita un escape cuando usas una expresión regular literal. Al crear la expresión regular con un objeto 'RegExp', no necesita un escape. Pero dado que doy un ejemplo con '/.../', es una buena idea mencionarlo. –

1

Realicé una búsqueda rápida en Google para ver qué hay y parece que tienes algunas opciones para escapar de los caracteres de expresiones regulares. De acuerdo con one page, puede definir & ejecutar una función como la de abajo para escapar caracteres problemáticos:

RegExp.escape = function(text) { 
    return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); 
} 

Alternativamente, se puede tratar de utilizar una biblioteca independiente, como XRegExp, que ya maneja los matices que está tratando de volver resolver.

4

Estoy sumergiendo los pies en Javascript, pero ¿hay alguna razón por la que necesite usar el motor de expresiones regulares? ¿Qué hay de

var sNeedle = '*Stars!*'; 
var sMySTR = 'The contents of this string have no importance'; 
if (sMySTR.indexOf(sNeedle) > -1) { 
    //found it 
} 
+0

Realmente no he pensado en esto. Simplemente estoy atrapado en mi cabeza que debería usar .search() .match() .replace() con cadenas. De hecho, todo lo que quiero hacer es usar sNeedle como una cadena de texto simple, así que creo que el indexOf es una buena idea. – user1651105

Cuestiones relacionadas