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?
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.
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.
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 " .
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")
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
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.