Utiliser une chaîne dynamique (variable) comme motif regex en JavaScript

Je veux Ajouter une balise (variable) aux valeurs avec regex, le modèle fonctionne bien avec PHP mais j'ai des problèmes pour l'implémenter en JavaScript.

Le modèle est (value est la variable):

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

J'ai échappé aux barres obliques inverses:

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 juste, j'ai enregistré le modèle et c'est exactement ce qu'il devrait être. Des idées?

40
demandé sur luschn 2013-07-26 19:55:10

4 réponses

Pour créer l'expression rationnelle en tant que chaîne, vous devez utiliser L'objet RegExp JavaScript.

En outre, vous pouvez faire correspondre/remplacer plus d'une fois. Dans ce cas, ajoutez l'indicateur g (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 jsfiddle ici.


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

Toutes les chaînes ne sont pas une expression rationnelle valide, cependant: il y a quelques caractères spéciaux, 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 jsfiddle ici.


Pour le cas spécifique, avis il n'y a pas de s (dotall) drapeau/modificateur en JavaScript. Lorsqu'il est disponible, il force généralement le point (.) à correspondre aux nouvelles lignes. Voici une solution possible pour votre cas:

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

Avis J'ai ajouté un ' manquant à la fin de "<a href='#" + value +"'>".

Voir la démo de violon ici. Vous pouvez également essayer Cette solution en utilisant le modificateur" g " .

89
répondu acdcjunior 2015-03-11 20:28:08

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")
8
répondu happytime harry 2013-07-26 15:58:02

J'ai trouvé ce fil utile-alors j'ai pensé que j'ajouterais 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 node en javascript et pour l'un des paramètres du fichier que je devais faire correspondre sur une chaîne, puis remplacer la ligne qui le suivait.

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, il changera le paramètre de répertoire de données existant pour le nouveau:

Fichier de configuration avant:

data_file_directories:  
   - /var/lib/cassandra/data

Fichier de configuration après:

data_file_directories:  
- /mnt/cassandra/data
3
répondu JRD 2016-03-03 13:22:48

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

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

Si value est 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, de sorte que vous pouvez 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 si value contient des caractères d'expressions régulières comme (, [ et ? vous devrez leur échapper.

2
répondu Halcyon 2013-07-26 16:05:00