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?

Borstenhorst
fuente
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 .

acdcjunior
fuente
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")
hombre polilla
fuente
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.

Martín pescador
fuente
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
JRD
fuente
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, "");
será
fuente
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
Alec Donald Mather
fuente
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

Vinu
fuente