6

En https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions está publicado el siguiente ejemplo:

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

¿Es esta la forma segura de escapar una cadena provista por usuario final, por ejemplo a través de un cuadro de diálogo?

Ejemplo:

/**
 * Ejemplo. Eliminar todas las instancias de una subcadena en una cadena.
 * 
 * Require dos entradas al usuario, cadena y subcadena.
 * Debemos asegurarnos que la subcadena es segura para ser procesada
 * como parte de una expresión regular.
 */

/** 
  * Tomado de 
  * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
  * ¿Es esto seguro?
  */
function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 
}

// Cadena a procesar
var cadena = "Test abc test test abc test test test abc test test abc";
var entradaUsuario1 = prompt("Escribe la cadena a procesar",cadena);

// Subcadena a eliminar
var subcadena = "abc";
var entradaUsuario2 = prompt("Escribe la subcadena a eliminar",subcadena);

// Aplicar la función para escapar la entrada de usuario
var re = new RegExp(escapeRegExp(entradaUsuario2),'g');

// Aplicar reemplazo
var resultado = entradaUsuario1.replace(re, '');

// Imprimir en la consola el resultado
console.log(resultado);
Rubén
  • 10,857
  • 6
  • 35
  • 79

1 Answers1

5

Es una forma segura, pero se están escapando caracteres por demás.

  • El ] sólo tiene un significado especial dentro de una clase de caracteres (cerrándola). Pero si ya estamos escapando los [, no podría haber ninguna clase dentro de la expresión regular.
  • El } sólo tiene un significado especial como fin del cuantificador de rango {m,n}. Y, de nuevo, si estamos escapando los {, no podría haber un cuantificador de este estilo dentro del regex.


Escapar metacaracteres

Los metacaracteres (o caracteres especiales) son exclusivamente:

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


La función simplificada:

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


Escapar metacaracteres en una clase de caracteres

Puede darse el caso en el que se desee agregar caracteres dentro de una clase de caracteres (entre corchetes), por ejemplo en

var re = new RegExp("\\S+{2,} [" + caracteres + "]{3,}")

En ese caso, se deben escapar:

^ (al principio)   \   ]   -


La función para escapar el contenido de una clase de caracteres:

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


Escapar metacaracteres en el texto de reemplazo

Al utilizar cadena.replace(re, reemplazo), existen algunos patrones de reemplazo que tienen un significado especial. Para garantizar que se está reemplazando por el valor literal, se deberían escapar los $ como $$ para:

$$   $&   $`   $'   $n (n es un dígito)

La función para escapar el texto de reemplazo:

function escaparReemplazoRegex(string) {
    return string.replace(/\$(?=[$&`'\d])/g, '$$$$');
}
Mariano
  • 23,777
  • 20
  • 70
  • 102
  • En la página enlazada en [metacaracteres](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Regular_Expressions#Utilizando_caracteres_especiales) no vienen tal cual los que has indicado. Me parece que vale la pena resaltar eso en particular si por tí mismo llegaste a concluir eso. – Rubén Feb 13 '17 at 15:37
  • @Rubén es el mejor enlace de metacaracteres que encontré en MDN. Como verás, ninguno de los que están listados tiene un significado si se escapan los que están en esta respuesta. El listado de metacaracteres es común a todos los dialectos (o *flavors*) de "*Perl-like regex*". Una fuente puede ser [PCRE doc](http://www.pcre.org/current/doc/html/pcre2pattern.html#SEC4), aunque es un enlace que complica más de lo que aclara. No obstante, agrego algo para aclarar. – Mariano Feb 13 '17 at 15:49
  • 1
    Me lo imaginé. Me parece que has hecho una gran labor de síntesis y transposición didáctica. Felicidades, aplausos, caravanas, ... (perdón si suena exagerado). – Rubén Feb 13 '17 at 15:52