Utilice una cadena dinámica (variable) como patrón de expresiones regulares en JavaScript


101

Quiero agregar una etiqueta (variable) a los valores con expresiones regulares, el patrón funciona bien con PHP pero tengo problemas para implementarlo en JavaScript.

El patrón es ( valuees la variable):

/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is

Escapé de las barras invertidas:

var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "<a href='#" + value +">" + value + "</a>"));

Pero esto parece no estar bien, registré el patrón y es exactamente lo que debería ser. ¿Algunas ideas?


Es valueuna variable?
— Dogbert

Respuestas:


172

Para crear la expresión regular a partir de una cadena, debe usar el RegExpobjeto de JavaScript .

Si también desea hacer coincidir / reemplazar más de una vez, debe agregar lag marca (coincidencia global) . He aquí un ejemplo:

var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Demostración de JSFiddle aquí.


En el caso general, escape la cadena antes de usarla como expresión regular:

Sin embargo, no todas las cadenas son expresiones regulares válidas: hay algunos caracteres especiales, como (o [. Para solucionar este problema, simplemente escape la cadena antes de convertirla en una expresión regular. Una función de utilidad para eso va en el siguiente ejemplo:

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

var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Demostración de JSFiddle aquí.



Nota: la expresión regular en la pregunta usa el smodificador, que no existía en el momento de la pregunta, pero existe , un indicador / modificador s( dotall ) en JavaScript, hoy .


2
esto es genial y el mejor ejemplo que he encontrado hasta ahora de usar una variable dinámica en una expresión regular, ¡gracias!
— Eolis

1
Para 2019 hay un s modificador, vea nuevamente el enlace MDN en la nota de respuesta.
— Nickensoul

@Nickensoul ¡Bien visto! ¡Gracias por el aviso!
— acdcjunior

let idr = new RegExp (variable + "$"); Table.find ({field: new RegExp (idr, 'i')}) Me gustó esto. Salud.
— Utkarsh

12

Si está intentando utilizar un valor de variable en la expresión, debe utilizar el "constructor" de RegExp.

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")

6

No necesitas "definir una expresión regular, así que solo:

var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax

Si valuees una variable y desea una expresión regular dinámica, entonces no puede usar esta notación; utilice la notación alternativa.

String.replace también acepta cadenas como entrada, por lo que puede hacer "fox".replace("fox", "bear");

Alternativa:

var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");

Tenga en cuenta que si valuecontiene caracteres de expresiones regulares como (, [y ?tendrá que escapar de ellos.


2
La primera opción no funcionaría a menos que busque la cadena "valor"
— mothmonsterman

@happytimeharry Parece que hay un conflicto entre las dos expresiones regulares que publicó.
— Halcyon

@Fritz van Campen parece que la intención del patrón, dado el ejemplo de su javascript, era usar una variable
— mothmonsterman

mismo problema aquí, parece haber algo mal con el indicador "es": "Error de sintaxis no detectado: indicadores no válidos suministrados al constructor RegExp 'is'"
— Borstenhorst

las banderas para el constructor de RegExp deben estar separadas. Pero aún así, la expresión regular no funciona.
— Borstenhorst

5

Encontré este hilo útil, así que pensé en agregar la respuesta a mi propio problema.

Quería editar un archivo de configuración de base de datos (datastax cassandra) desde una aplicación de nodo en javascript y para una de las configuraciones en el archivo necesitaba hacer coincidir en una cadena y luego reemplazar la línea que la sigue.

Esta fue mi solución.

dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'

// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
    // need to use double escape '\\' when putting regex in strings !
    var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
    var myRegExp = new RegExp(searchString + re, "g");
    var match = myRegExp.exec(data);
    var replaceThis = match[1];
    var writeString = data.replace(replaceThis, newString);
    fs.writeFile(file, writeString, 'utf-8', function (err) {
    if (err) throw err;
        console.log(file + ' updated');
    });
});
}

searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"

replaceStringNextLine(dse_cassandra_yaml, searchString, newString );

Después de ejecutarse, cambiará la configuración del directorio de datos existente a la nueva:

archivo de configuración antes:

data_file_directories:  
   - /var/lib/cassandra/data

archivo de configuración después de:

data_file_directories:  
- /mnt/cassandra/data

4

Descubrí que tenía que hacer doble barra \ b para que funcionara. Por ejemplo, para eliminar las palabras "1x" de una cadena usando una variable, necesitaba usar:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");

Trabajó para mi. Gracias,
— Pravin Bhapkar

1

Manera mucho más fácil: use literales de plantilla.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false

0
var string = "Hi welcome to stack overflow"
var toSearch = "stack"

//case insensitive search

var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'

https://jsfiddle.net/9f0mb6Lz/

Espero que esto ayude

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.