Utiliser une chaîne dynamique (variable) comme modèle d'expression régulière dans JavaScript

101

Je veux ajouter une balise (variable) aux valeurs avec regex, le modèle fonctionne bien avec PHP mais j'ai du mal à l'implémenter dans JavaScript.

Le modèle est ( valueest la variable):

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

J'ai échappé aux contre-obliques:

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

Mais cela ne semble pas être correct, j'ai enregistré le modèle et c'est exactement ce qu'il devrait être. Des idées?

Borstenhorst
la source
Est-ce valueune variable?
Dogbert

Réponses:

173

Pour créer l'expression régulière à partir d'une chaîne, vous devez utiliser l' RegExpobjet JavaScript .

Si vous souhaitez également faire correspondre / remplacer plusieurs fois, vous devez ajouter l' gindicateur (correspondance globale) . Voici un exemple:

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.

Démo de JSFiddle ici.


Dans le cas général, échappez à la chaîne avant de l'utiliser comme regex:

Cependant, toutes les chaînes ne sont pas des expressions régulières valides: il existe des caractères spécifiques, comme (ou [. Pour contourner ce problème, échappez simplement la chaîne avant de la transformer en regex. Une fonction utilitaire pour cela va dans l'exemple ci-dessous:

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.

Démo de JSFiddle ici.



Remarque: l'expression régulière dans la question utilise le smodificateur, qui n'existait pas au moment de la question, mais qui existe - un indicateur / modificateur s( dotall ) en JavaScript - aujourd'hui .

acdcjunior
la source
2
c'est génial et le meilleur exemple que j'ai trouvé jusqu'à présent d'utilisation d'une variable dynamique dans une regex, merci!
Eolis
1
Pour 2019, il y a un s modificateur, voir à nouveau le lien MDN dans la note de réponse.
Nickensoul
@Nickensoul Bien repéré! Merci pour l'information!
acdcjunior
let idr = new RegExp (variable + "$"); Table.find ({field: new RegExp (idr, 'i')}) J'ai aimé ça. À votre santé.
Utkarsh
12

Si vous essayez d'utiliser une valeur de variable dans l'expression, vous devez utiliser le "constructeur" RegExp.

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

Vous n'avez pas besoin de "pour définir une expression régulière, donc simplement:

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

Si valueest une variable et que vous voulez une expression régulière dynamique, vous ne pouvez pas utiliser cette notation; utilisez la notation alternative.

String.replace accepte également les chaînes en entrée, vous pouvez donc faire "fox".replace("fox", "bear");

Alternative:

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");

Gardez à l'esprit que if valuecontient des caractères d'expressions régulières comme (, [et ?vous devrez les échapper.

Alcyon
la source
2
La première option ne fonctionnerait pas à moins de rechercher la chaîne "valeur"
mothmonsterman
@happytimeharry Il semble qu'il y ait un conflit entre les deux expressions rationnelles qu'il a postées.
Halcyon
@Fritz van Campen il semble que l'intention du modèle, étant donné l'exemple de son javascript, était d'utiliser une variable
mothmonsterman
même problème ici, il semble y avoir quelque chose qui ne va pas avec l'indicateur "is": "Uncaught SyntaxError: Les indicateurs non valides fournis au constructeur RegExp 'is'"
Borstenhorst
les indicateurs pour le constructeur de RegExp doivent être séparés. Mais le regex ne fonctionne toujours pas.
Borstenhorst
5

J'ai trouvé ce fil utile - j'ai donc pensé ajouter la réponse à mon propre problème.

Je voulais éditer un fichier de configuration de base de données (datastax cassandra) à partir d'une application de nœud en javascript et pour l'un des paramètres du fichier dont j'avais besoin pour correspondre sur une chaîne, puis remplacer la ligne qui le suit.

C'était ma solution.

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 );

Après l'exécution, le paramètre du répertoire de données existant sera remplacé par le nouveau:

fichier de configuration avant:

data_file_directories:  
   - /var/lib/cassandra/data

fichier de configuration après:

data_file_directories:  
- /mnt/cassandra/data
JRD
la source
4

J'ai trouvé que je devais doubler le \ b pour le faire fonctionner. Par exemple, pour supprimer les mots "1x" d'une chaîne à l'aide d'une variable, j'avais besoin d'utiliser:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");
volonté
la source
A travaillé pour moi. Merci,
Pravin Bhapkar le
1

Méthode beaucoup plus simple: utilisez des littéraux de modèle.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Alec Donald Mather
la source
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/

J'espère que cela t'aides

Vinu
la source