La mayoría de las expresiones aquí resuelven casos de uso específicos individuales.
Eso está bien, pero prefiero un enfoque de "siempre funciona".
function regExpEscape(literal_string) {
return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}
Esto "escapará completamente" de una cadena literal para cualquiera de los siguientes usos en expresiones regulares:
- Inserción en una expresión regular. P.ej
new RegExp(regExpEscape(str))
- Inserción en una clase de personaje. P.ej
new RegExp('[' + regExpEscape(str) + ']')
- Inserción en el especificador de conteo entero. P.ej
new RegExp('x{1,' + regExpEscape(str) + '}')
- Ejecución en motores de expresión regular que no sean JavaScript.
Caracteres especiales cubiertos:
-
: Crea un rango de caracteres en una clase de caracteres.
[
/ ]
: Inicia / finaliza una clase de caracteres.
{
/ }
: Inicia / finaliza un especificador de numeración.
(
/ )
: Inicia / finaliza un grupo.
*
/ +
/ ?
: Especifica el tipo de repetición.
.
: Coincide con cualquier personaje.
\
: Escapa de caracteres e inicia entidades.
^
: Especifica el inicio de la zona de coincidencia y niega la coincidencia en una clase de caracteres.
$
: Especifica el final de la zona coincidente.
|
: Especifica la alternancia.
#
: Especifica el comentario en el modo de espacio libre.
\s
: Ignorado en el modo de espacio libre.
,
: Separa los valores en el especificador de numeración.
/
: Inicia o finaliza la expresión.
:
: Completa tipos de grupos especiales y parte de las clases de personajes de estilo Perl.
!
: Niega el grupo de ancho cero.
<
/ =
: Parte de las especificaciones de grupo de ancho cero.
Notas:
/
no es estrictamente necesario en ningún sabor de expresión regular. Sin embargo, protege en caso de que alguien (estremecimiento) lo haga eval("/" + pattern + "/");
.
,
garantiza que si la cadena está destinada a ser un número entero en el especificador numérico, provocará correctamente un error de compilación RegExp en lugar de compilar en silencio incorrectamente.
#
, y \s
no necesita ser escapado en JavaScript, pero sí en muchos otros sabores. Aquí se escapan en caso de que la expresión regular se pase luego a otro programa.
Si también necesita probar la expresión regular en el futuro contra posibles adiciones a las capacidades del motor de expresión regular 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 a todos los caracteres, excepto aquellos explícitamente garantizados que no se utilizarán para la sintaxis en futuros sabores de expresiones regulares.
Para los verdaderamente interesados en el saneamiento, considere este caso extremo:
var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');
Esto debería compilarse bien en JavaScript, pero no en otros sabores. 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) : '') + ')');
RegExp.escape
se trabaja actualmente y cualquier persona que piense que tiene un aporte valioso es bienvenido a contribuir. core-js y otros polyfills lo ofrecen.