Javascript Regex: ¿Cómo poner una variable dentro de una expresión regular?

206

Así por ejemplo:

function(input){
    var testVar = input;
    string = ...
    string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}

Pero esto, por supuesto, no funciona :) ¿Hay alguna manera de hacer esto?

Adán
fuente
11
Tenga en cuenta que si deja que el usuario proporcione esta variable, es fácil que un usuario malintencionado bloquee su aplicación a través de un seguimiento catastrófico.
Tim Pietzcker
2
¿Qué es "ReGeX"? ¿Es un nombre variable? hace que las respuestas sean confusas al implicar que es parte de la construcción de RegExp (en caso de que un lector no haya visto esos caracteres extraños en la pregunta).
Eduard

Respuestas:

272
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");

Actualizar

Según algunos de los comentarios, es importante tener en cuenta que es posible que desee escapar de la variable si existe la posibilidad de contenido malicioso (por ejemplo, la variable proviene de la entrada del usuario)

Actualización ES6

En 2019, esto generalmente se escribiría usando una cadena de plantilla, y el código anterior se ha actualizado. La respuesta original fue:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
Jason McCreary
fuente
55
¡Asegúrate de escapar de tu cuerda! Vea la respuesta de @zzzzBov
jtpereyda
Esto no funciona en mi caso, ¿pueden echarle un vistazo a este jsfiddle y decirme si tengo que hacer si quiero establecer una regexexpresión dinámica de código de país?
Kirankumar Dafda
10
Una cosa importante para recordar es que en las cadenas regulares el carácter \ necesita ser escapado mientras que en el literal regex (generalmente) el carácter / necesita ser escapado. Así se /\w+\//iconviertenew RegExp("\\w+/", "i")
Ali
3
¿Qué tal el / g?
Qian Chen
Chicos, necesito dividir esta expresión regular /[^0-9.-font>/g en dos partes: / [^ 0-9 y -] / g ¿Cómo hacerlo?
max
79

Puede usar el objeto RegExp:

var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);

Entonces puedes construir regexstringde la forma que quieras.

Puedes leer más sobre esto aquí .

steinar
fuente
var characterCount = parseInt (attrs.limitCharacterCount); console.log (characterCount); var specialCharactersValidation = new RegExp ("/ ^ [a-zA-Z0-9] {" + characterCount + "} $ /"); / \ / ^ [a-zA-Z0-9] {7} $ \ // requestShipmentDirectives.js: 76 false main.js: 46 Tipo de error no capturado: No se puede leer la propiedad 'offsetWidth' de nulo Esto es lo que sucede cuando hago la dinámica de RegEx.
Ankit Tanna
31

Para construir una expresión regular a partir de una variable en JavaScript, deberá usar el RegExpconstructor con un parámetro de cadena.

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

Por supuesto, este es un ejemplo muy ingenuo. Se supone que inputse ha escapado correctamente para una expresión regular. Si está tratando con la entrada del usuario, o simplemente desea que sea más conveniente que coincida con caracteres especiales, deberá escapar de caracteres especiales :

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

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    input = regexEscape(input);
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
zzzzBov
fuente
La única forma en que esto funcionó para mí fue si borraba el ReGeXtexto. Entonces solía:return new RegExp(input, flags);
Michael Rader
2
@MichaelRader, sí, el texto "ReGeX" fue parte de la pregunta y se usó como ejemplo, no como algo necesario para que el código funcione.
zzzzBov
1
jajaja, me di cuenta de que solo era tu marcador de posición, pero como novato, me tomó un tiempo darme cuenta. Gracias.
Michael Rader
Entiendo por qué la cadena necesita escapar. Pero, ¿por qué '\\ $ &' ​​se usa como reemplazo
Sherin Binu
2
\\representa un solo \carácter, $&es la subcadena coincidente .
zzzzBov
7

si está utilizando los literales de plantilla es6 son una opción ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
shunryu111
fuente
no funciona con literales de plantilla. Estoy usando regexp para validar la contraseña en mi aplicación, y quería parametrizar la longitud máxima y mínima en mi cadena de expresión regular y no funciona. `` `const newRegExp = nuevo RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = value => value.match (newRegExp); `` `
p7adams
6

Siempre puede dar una expresión regular como cadena, es decir "ReGeX" + testVar + "ReGeX" . Posiblemente tenga que escapar de algunos caracteres dentro de su cadena (por ejemplo, comillas dobles), pero en la mayoría de los casos es equivalente.

También puede usar el RegExpconstructor para pasar banderas ( ver los documentos ).

Nikita Rybak
fuente
3

Puede crear expresiones regulares en JS de una de dos maneras:

  1. Usando la expresión regular literal - /ab{2}/g
  2. Usando el constructor de expresiones regulares - new RegExp("ab{2}", "g").

Los literales de expresión regular son constantes y no se pueden usar con variables. Esto podría lograrse utilizando el constructor. La extracción del constructor RegEx es

new RegExp(regularExpressionString, modifiersString)

Puede incrustar variables como parte de regularExpressionString. Por ejemplo,

var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g") 

Esto coincidirá con cualquier apariencia del patrón cdcdcd.

Ben Carp
fuente
2

Aquí hay una función bastante inútil que devuelve valores envueltos por caracteres específicos. :)

jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/

function getValsWrappedIn(str,c1,c2){
    var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g"); 
    return str.match(rg);
    }

var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results =  getValsWrappedIn(exampleStr,"(",")")

// Will return array ["5","19","thingy"]
console.log(results)
Jakob Sternberg
fuente
2

la respuesta aceptada no funciona para mí y no sigue los ejemplos de MDN

ver la sección 'Descripción' en el enlace de arriba

Iría con lo siguiente, me está funcionando:

let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)

// that makes dynamicRegExp = /findMe/gi
Timothy Mitchell
fuente
1
Aún funciona. El problema es que 'ReGeX' + testVar + 'ReGeX' hace que la solución sea confusa. Agregar un ejemplo real aclararía las cosas en mi opinión. var testVar = '321'; var regex = new RegExp ("[" + testVar + "] {2}", "g"); // arriba equivalente a / [321] {2} / g
HelloWorldPeace
1

Solo es necesario preparar primero la variable de cadena y luego convertirla a RegEx.

por ejemplo:

Desea agregar minLengthy MaxLengthcon la variable a RegEx:

function getRegEx() {
    const minLength = "5"; // for exapmle: min is 5
    const maxLength = "12"; // for exapmle: man is 12

    var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
    regEx = new RegExp(regEx, "g"); // now we convert it to RegEx

    return regEx; // In the end, we return the RegEx
}

ahora si cambia el valor de MaxLengtho MinLength, cambiará en todos los RegExs.

Espero ser de utilidad. También lamento mi inglés.

Abbas Habibnejad
fuente