2010-04-07 20 views
90

Tengo un código como:¿Cómo escapar de la expresión regular en javascript?

pattern = 'arrayname[1]'; // fetch from dom, make literal here just for example 
reg = new RegExp(RegExp.quote(pattern), 'g'); 
mystring.replace(reg, 'arrayname[2]'); 

pero falla con un mensaje de error que dice: "RegExp.quote no es una función".

¿Echo de menos algo simple?

+1

Tenga en cuenta que estamos actualmente [trabajando en agregar esta diversión ctionality to JavaScript] (https://github.com/benjamingr/RegExp.escape) si tiene una opinión al respecto, únase a la discusión. –

Respuesta

167

Esta pregunta me hizo buscar en Google una función RegEx.quote en JavaScript, que no conocía. Resulta que la función existe en un solo lugar, es decir, en un answer by Gracenote here on StackOverflow. La función se define de esta manera:

RegExp.quote = function(str) { 
    return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); 
}; 

Si desea utilizar esta función, deberá incluir la definición anterior en algún lugar por encima del punto en el que se utiliza la función en el script.

+44

¡Ahora SO genera respuestas a problemas incluso antes de que existan! – RedFilter

+6

Esa es una función ordenada, pero es importante tener cuidado con cosas así. Solo funciona cuando sabes que la cadena que contiene el patrón realmente no tiene la intención de ser interpretada con metacaracteres de expresiones regulares reales. – Pointy

+0

@Pointy: ¡Solo puedo estar de acuerdo! –

2

Bueno, en primer lugar se puede definir la expresión regular con su propia sintaxis constante:

var reg = /arrayname\[1\]/; 

Dentro de la expresión regular que citar cosas con barra invertida. Ahora, si estás comenzando desde una cuerda, tienes que "proteger" esas barras invertidas dentro de la constante de cadena. En ese caso, el patrón se está analizando dos veces: una vez cuando la constante de cadena es engullido por el intérprete de Javascript, y luego una vez por el constructor RegExp:

var pattern = "arrayname\\[1\\]"; 
var reg = new RegExp(pattern); 

Las barras invertidas son dos de manera que la cadena "patrón "se verá como la expresión regular en mi primer ejemplo: una barra invertida antes de cada carácter de paréntesis.

+0

Lo que pasa es que no sabemos cuál será la cadena. – levhita

24

Si desea reemplazar, literalmente, no se necesita una expresión regular en el primer lugar:

str = str.split(search).join(replace) 
+4

Upvoted, pero algunas veces necesita combinar la entrada del usuario con su propia expresión regular, en cuyo caso no podría simplemente hacer lo anterior. –

22

Desde el mozilla dev docs

function escapeRegExp(string){ 
    return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 
} 

Esto está fuera de lo común, pero en este escenario en particular, que crearía una función como esta

RegExp.escape = function(str) { 
    return String(str).replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); 
}; 

Uso

new RegExp(RegExp.escape('http://www.google.com')); 
//=> /http\:\/\/www\.google\.com/ 
15

Aquí está la función exacta que utiliza la biblioteca de cierre de Google.

/** 
* Escapes characters in the string that are not safe to use in a RegExp. 
* @param {*} s The string to escape. If not a string, it will be casted 
*  to one. 
* @return {string} A RegExp safe, escaped copy of {@code s}. 
*/ 
goog.string.regExpEscape = function(s) { 
    return String(s).replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1'). 
     replace(/\x08/g, '\\x08'); 
}; 

Ver link

+1

Pero me pregunto por qué diablos están reemplazando '\ x08' en particular. Ya sabes lo que dicen, Google funciona de maneras misteriosas. –

+0

@CamiloMartin Porque '\ b' afirma el límite de palabras en Expresiones regulares pero es el escape de un solo carácter para Retroceso en las cadenas ' /\b/.test('\b '); // false' '/\x08/.test('\b '); // verdadero' – Xaekai

+0

@Xaekai Son dos contextos de análisis diferentes. cuando escribes '\ b' en una cadena, se convierte en' \ x08', pero dudo que '\ b' se convierta internamente en' \ x08' cuando se escribe en un literal de expresión regular. Ver (probado en Chrome): '(nuevo RegExp ('\ x08')). Test ('word boundary') === false'. Pero lo que dices está tan cerca de tener sentido, quizás algunos antiguos analizadores de IE '\ b' en' \ x08' para RegExp. –

15
var easiest = any_string.replace(/\W/g, "\\$&"); 

EDIT:

¿Por qué debería recordar que los personajes tienen un significado especial o incluso el uso de una función si se escape ninguna palabra no es suficiente carácter?

Mi solución es obvia, tal vez por eso se baja la votación. : D

+1

Hahaha. Abajo votame tanto como puedas. : D – Ando

+0

¿Por qué se ha votado negativamente? –

+2

Creo que esto no debe ser downvoted porque el siguiente artículo parece bastante sólido y recomienda una versión ligeramente mejorada, aunque todavía no estoy muy seguro de qué casos adicionales cubriría: 'str.reemplace (/ [^ \ w \ s]/g, "\\ $ &") 'http://eloquentjavascript.net/09_regexp.html _ (por cierto, no lo confunda con_' str.replace (/ [\ W \ S ]/g, "\\ $ &") '_como se explica aquí: http://www.regular-expressions.info/shorthand.html)_ –

4

Las respuestas anteriores escapan demasiados caracteres.

Según What special characters must be escaped in regular expressions?, sólo los siguientes caracteres tienen que ser escapado:

  • .^$*+?()[{\| clases de personajes fuera.
  • ^-]\ dentro de las clases de caracteres.

Entonces, esta función hace el truco:

function escapeRegExp(str) { 
    return str.replace(/[.^$*+?()[{\\|\]-]/g, '\\$&'); 
} 
Cuestiones relacionadas