¿Existe una función RegExp.escape en JavaScript?

Resuelto Lance asked hace 14 años • 20 respuestas

Sólo quiero crear una expresión regular a partir de cualquier cadena posible.

var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);

¿Existe algún método integrado para eso? Si no, ¿qué usa la gente? Rubí tiene RegExp.escape. No siento que necesite escribir el mío propio, tiene que haber algo estándar por ahí.

Lance avatar Aug 25 '10 05:08 Lance
Aceptado

La función vinculada en otra respuesta es insuficiente. No logra escapar ^de or $(inicio y final de la cadena), o -, que en un grupo de caracteres se usa para rangos.

Utilice esta función:

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

Si bien puede parecer innecesario a primera vista, el escape -(así como ^) hace que la función sea adecuada para insertar caracteres de escape en una clase de caracteres, así como en el cuerpo de la expresión regular.

El escape /hace que la función sea adecuada para caracteres de escape que se utilizarán en un literal de expresiones regulares de JavaScript para su posterior evaluación.

Como no hay ningún inconveniente en escapar de cualquiera de ellos, tiene sentido escapar para cubrir casos de uso más amplios.

Y sí, es un error decepcionante que esto no forme parte del JavaScript estándar.

bobince avatar Aug 24 '2010 23:08 bobince

Para cualquiera que use Lodash, desde v3.0.0 hay una función _.escapeRegExp incorporada:

_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'

Y, en el caso de que no desee requerir la biblioteca Lodash completa, ¡puede necesitar solo esa función !

gustavohenke avatar Apr 17 '2015 13:04 gustavohenke

La mayoría de las expresiones aquí resuelven casos de uso específicos únicos.

Está bien, pero prefiero un enfoque de "siempre funciona".

function regExpEscape(literal_string) {
    return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}

Esto "escapará completamente" una cadena literal para cualquiera de los siguientes usos en expresiones regulares:

  • Inserción en una expresión regular. P.ejnew RegExp(regExpEscape(str))
  • Inserción en una clase de personaje. P.ejnew RegExp('[' + regExpEscape(str) + ']')
  • Inserción en el especificador de recuento de números enteros. P.ejnew RegExp('x{1,' + regExpEscape(str) + '}')
  • Ejecución en motores de expresiones regulares que no sean JavaScript.

Personajes especiales cubiertos:

  • -: Crea un rango de caracteres en una clase de caracteres.
  • [/ ]: Inicia / finaliza una clase de personaje.
  • {/ }: Inicia / finaliza un especificador de numeración.
  • (/ ): Inicia / finaliza un grupo.
  • *// +: ?Especifica el tipo de repetición.
  • .: Coincide con cualquier carácter.
  • \: escapa de los personajes e inicia entidades.
  • ^: Especifica el inicio de la zona de coincidencia y niega la coincidencia en una clase de carácter.
  • $: Especifica el final de la zona coincidente.
  • |: Especifica la alternancia.
  • #: Especifica comentario en modo de espacio libre.
  • \s: Ignorado en modo de espaciado libre.
  • ,: Separa valores en el especificador de numeración.
  • /: Inicia o finaliza la expresión.
  • :: Completa tipos de grupos especiales y forma parte de clases de caracteres estilo Perl.
  • !: Niega el grupo de ancho cero.
  • </ =: Parte de las especificaciones del grupo de ancho cero.

Notas:

  • /no es estrictamente necesario en ningún tipo de expresión regular. Sin embargo, protege en caso de que alguien (estremecimiento) lo haga eval("/" + pattern + "/");.
  • ,garantiza que si la cadena debe ser un número entero en el especificador numérico, provocará correctamente un error de compilación de RegExp en lugar de una compilación incorrecta silenciosa.
  • #, y \sno es necesario escapar en JavaScript, pero sí en muchas otras versiones. Se utilizan como escape aquí en caso de que la expresión regular se pase más adelante a otro programa.

Si también necesita preparar la expresión regular para el futuro contra posibles adiciones a las capacidades del motor de expresiones regulares de JavaScript, le recomiendo usar el más paranoico:

function regExpEscapeFuture(literal_string) {
    return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}

Esta función escapa de todos los caracteres, excepto aquellos que se garantiza explícitamente que no se utilizarán para la sintaxis en futuros tipos de expresiones regulares.


Para aquellos verdaderamente interesados ​​en el saneamiento, consideren este caso extremo:

var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');

Esto debería compilarse bien en JavaScript, pero no en otras versiones. Si tiene la intención de pasar a otro sabor, el caso nulo de s === ''debe verificarse de forma independiente, así:

var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
Pi Marillion avatar Jun 15 '2015 17:06 Pi Marillion

La Guía de expresiones regulares de Mozilla Developer Network proporciona esta función de escape:

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
quietmint avatar May 13 '2014 17:05 quietmint

En el widget de autocompletar de jQuery UI (versión 1.9.1), usan una expresión regular ligeramente diferente (línea 6753), aquí está la expresión regular combinada con el enfoque de bobince .

RegExp.escape = function( value ) {
     return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
Pierluc SS avatar Oct 31 '2012 12:10 Pierluc SS