Javascript Regex: Comment mettre une variable dans une expression régulière?

206

Ainsi, par exemple:

function(input){
    var testVar = input;
    string = ...
    string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}

Mais cela ne fonctionne bien sûr pas :) Existe-t-il un moyen de procéder?

Adam
la source
11
Sachez que si vous laissez l'utilisateur fournir cette variable, il est facile pour un utilisateur malveillant de planter votre application via un retour en arrière catastrophique.
Tim Pietzcker
2
qu'est-ce que "ReGeX"? est-ce un nom de variable? cela rend les réponses confuses en impliquant qu'il fait partie de la construction de RegExp (au cas où un lecteur n'aurait pas vu ces personnages étranges dans la question).
Eduard

Réponses:

272
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");

Mettre à jour

Selon certains des commentaires, il est important de noter que vous pouvez vouloir échapper à la variable s'il y a un potentiel de contenu malveillant (par exemple, la variable provient de la saisie de l'utilisateur)

Mise à jour ES6

En 2019, cela serait généralement écrit à l'aide d'une chaîne de modèle, et le code ci-dessus a été mis à jour. La réponse originale était:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
Jason McCreary
la source
5
Assurez-vous d'échapper à votre chaîne! Voir la réponse @zzzzBov
jtpereyda
Cela ne fonctionne pas dans mon cas, pouvez-vous s'il vous plaît jeter un oeil à ce jsfiddle et me faire savoir si ce que je dois faire si je veux définir une dynamique de code de pays dans l' regexexpression
Kirankumar Dafda
10
Une chose importante à retenir est que dans les chaînes régulières, le caractère \ doit être échappé tandis que dans le littéral regex (généralement), le caractère / doit être échappé. Alors /\w+\//idevientnew RegExp("\\w+/", "i")
Ali
3
Et le / g?
Qian Chen
Les gars, j'ai besoin de diviser cette expression régulière /[^0-9.- diplomatique/g en deux parties: / [^ 0-9 et -] / g Comment faire?
max
79

Vous pouvez utiliser l'objet RegExp:

var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);

Ensuite, vous pouvez construire regexstringcomme vous le souhaitez.

Vous pouvez en savoir plus ici .

steinar
la source
var characterCount = parseInt (attrs.limitCharacterCount); console.log (characterCount); var specialCharactersValidation = new RegExp ("/ ^ [a-zA-Z0-9] {" + characterCount + "} $ /"); / \ / ^ [a-zA-Z0-9] {7} $ \ // requestShipmentDirectives.js: 76 false main.js: 46 Uncaught TypeError: Impossible de lire la propriété 'offsetWidth' de null C'est ce qui se passe lorsque je crée le RegEx Dynamic.
Ankit Tanna
31

Pour créer une expression régulière à partir d'une variable en JavaScript, vous devrez utiliser le RegExpconstructeur avec un paramètre de chaîne.

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

bien sûr, c'est un exemple très naïf. Il suppose qu'il inputa été correctement échappé pour une expression régulière. Si vous avez affaire à une saisie utilisateur ou si vous souhaitez simplement faciliter la mise en correspondance de caractères spéciaux, vous devrez échapper les caractères spéciaux :

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

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    input = regexEscape(input);
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}
zzzzBov
la source
La seule façon dont cela fonctionnait pour moi était de supprimer du ReGeXtexte. J'ai donc utilisé:return new RegExp(input, flags);
Michael Rader
2
@MichaelRader, oui, le texte "ReGeX" faisait partie de la question et utilisé comme exemple, pas comme quelque chose qui est nécessaire pour faire fonctionner le code.
zzzzBov
1
lol vient de réaliser que c'était juste votre espace réservé, mais en tant que noob, cela m'a pris un certain temps à comprendre. Merci.
Michael Rader
Je comprends pourquoi la chaîne doit être échappée. Mais pourquoi '\\ $ &' ​​est utilisé en remplacement
Sherin Binu
2
\\représente un seul \caractère, $&est la sous-chaîne correspondante .
zzzzBov
7

si vous utilisez le modèle es6, les littéraux sont une option ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
shunryu111
la source
cela ne fonctionne pas avec les littéraux de modèle. J'utilise regexp pour valider le mot de passe dans mon application, et je voulais paramétrer la longueur maximale et minimale dans ma chaîne d'expression régulière et cela ne fonctionne pas. `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = value => value.match (newRegExp); ``
p7adams
6

Vous pouvez toujours donner une expression régulière sous forme de chaîne, c'est-à-dire "ReGeX" + testVar + "ReGeX". Vous devrez peut-être échapper certains caractères à l'intérieur de votre chaîne (par exemple, les guillemets doubles), mais dans la plupart des cas, c'est équivalent.

Vous pouvez également utiliser le RegExpconstructeur pour passer des drapeaux ( voir la documentation ).

Nikita Rybak
la source
3

Vous pouvez créer des expressions régulières dans JS de deux manières:

  1. Utilisation d'un littéral d'expression régulière - /ab{2}/g
  2. Utilisation du constructeur d'expressions régulières - new RegExp("ab{2}", "g").

Les littéraux d'expression régulière sont constants et ne peuvent pas être utilisés avec des variables. Cela pourrait être réalisé en utilisant le constructeur. La structure du constructeur RegEx est

new RegExp(regularExpressionString, modifiersString)

Vous pouvez incorporer des variables dans le cadre de regularExpressionString. Par exemple,

var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g") 

Cela correspondra à toute apparence du motif cdcdcd.

Ben Carp
la source
2

Voici une fonction assez inutile qui retourne des valeurs enveloppées par des caractères spécifiques. :)

jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/

function getValsWrappedIn(str,c1,c2){
    var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g"); 
    return str.match(rg);
    }

var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results =  getValsWrappedIn(exampleStr,"(",")")

// Will return array ["5","19","thingy"]
console.log(results)
Jakob Sternberg
la source
2

la réponse acceptée ne fonctionne pas pour moi et ne suit pas les exemples MDN

voir la section «Description» dans le lien ci-dessus

J'irais avec ce qui suit, cela fonctionne pour moi:

let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)

// that makes dynamicRegExp = /findMe/gi
Timothy Mitchell
la source
1
Ça fonctionne encore. Le problème est que 'ReGeX' + testVar + 'ReGeX' rend la solution déroutante. L'ajout d'un exemple concret éclaircirait les choses à mon avis. var testVar = '321'; var regex = new RegExp ("[" + testVar + "] {2}", "g"); // équivalent ci-dessus à / [321] {2} / g
HelloWorldPeace
1

Il suffit de préparer d'abord la variable de chaîne, puis de la convertir en RegEx.

par exemple:

Vous souhaitez ajouter minLengthet MaxLengthavec la variable à RegEx:

function getRegEx() {
    const minLength = "5"; // for exapmle: min is 5
    const maxLength = "12"; // for exapmle: man is 12

    var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
    regEx = new RegExp(regEx, "g"); // now we convert it to RegEx

    return regEx; // In the end, we return the RegEx
}

maintenant si vous changez la valeur de MaxLengthou MinLength, cela changera dans tous les RegEx.

J'espère être utile. Désolé aussi pour mon anglais.

Abbas Habibnejad
la source