Javascript Regex: Wie füge ich eine Variable in einen regulären Ausdruck ein?

206

Also zum Beispiel:

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

Aber das funktioniert natürlich nicht :) Gibt es eine Möglichkeit, dies zu tun?

Adam
quelle
11
Beachten Sie, dass ein böswilliger Benutzer Ihre Anwendung durch katastrophales Backtracking leicht zum Absturz bringen kann, wenn Sie den Benutzer diese Variable angeben lassen.
Tim Pietzcker
2
Was ist "ReGeX"? ist es ein Variablenname? Es macht Antworten verwirrend, indem es impliziert, dass es Teil der RegExp-Konstruktion ist (falls ein Leser diese seltsamen Zeichen in der Frage nicht gesehen hat).
Eduard

Antworten:

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

Aktualisieren

Per einige der Kommentare, ist es wichtig zu beachten , dass Sie möchten entkommen die Variable , wenn es auf schädliche Inhalte (zB die Variable kommt von Benutzereingaben) Potential

ES6-Update

Im Jahr 2019 wird dies normalerweise mit einer Vorlagenzeichenfolge geschrieben, und der obige Code wurde aktualisiert. Die ursprüngliche Antwort war:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
Jason McCreary
quelle
5
Stellen Sie sicher, dass Sie Ihrer Schnur entkommen! Siehe @zzzzBov Antwort
jtpereyda
Dies funktioniert in meinem Fall nicht. Können Sie sich bitte diese jsfiddle ansehen und mich wissen lassen, was ich tun muss, wenn ich eine Ländercode-Dynamik in regexAusdruck
bringen möchte
10
Eine wichtige Sache, an die Sie sich erinnern sollten, ist, dass in regulären Zeichenfolgen das Zeichen \ maskiert werden muss, während im regulären Regex-Literal (normalerweise) das Zeichen / maskiert werden muss. So /\w+\//iwirdnew RegExp("\\w+/", "i")
Ali
3
Wie wäre es mit dem / g?
Qian Chen
Leute, ich muss diesen regulären Ausdruck /[^0-9.-‹/g durch zwei Teile teilen: / [^ 0-9 und -] / g Wie geht das?
Max
79

Sie können das RegExp-Objekt verwenden:

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

Dann können Sie konstruieren regexstring .

Sie können mehr darüber lesen Sie hier .

Steinar
quelle
var charakterCount = 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 Nicht erfasster Typfehler: Die Eigenschaft 'offsetWidth' von null kann nicht gelesen werden. Dies geschieht, wenn ich mache die RegEx Dynamic.
Ankit Tanna
31

Um einen regulären Ausdruck aus einer Variablen in JavaScript zu erstellen, müssen Sie den RegExpKonstruktor mit einem Zeichenfolgenparameter verwenden.

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

Dies ist natürlich ein sehr naives Beispiel. Es wird davon ausgegangen, dass inputes für einen regulären Ausdruck ordnungsgemäß maskiert wurde. Wenn Sie sich mit Benutzereingaben befassen oder einfach das Abgleichen von Sonderzeichen vereinfachen möchten, müssen Sie Sonderzeichen umgehen :

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
quelle
Das hat bei mir nur funktioniert, wenn ich ReGeXText gelöscht habe . Also habe ich verwendet:return new RegExp(input, flags);
Michael Rader
2
@MichaelRader, ja, der "ReGeX" -Text war Teil der Frage und wurde als Beispiel verwendet, nicht als etwas, das erforderlich ist, damit der Code funktioniert.
zzzzBov
1
lol habe gerade gemerkt, dass das nur dein Platzhalter war, aber als Noob habe ich eine Weile gebraucht, um das herauszufinden. Vielen Dank.
Michael Rader
Ich verstehe, warum Zeichenfolge maskiert werden muss. Aber warum wird '\\ $ &' ​​als Ersatz verwendet
Sherin Binu
2
\\stellt ein einzelnes \Zeichen dar, $&ist der übereinstimmende Teilstring .
zzzzBov
7

wenn Sie es6 verwenden Vorlagenliterale verwenden, sind diese eine Option ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
shunryu111
quelle
Es funktioniert nicht mit Vorlagenliteralen. Ich verwende regexp, um das Kennwort in meiner App zu überprüfen, und ich wollte die maximale und minimale Länge in meiner Zeichenfolge für reguläre Ausdrücke parametrisieren. Dies funktioniert nicht. `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = value => value.match (newRegExp); `` `
p7adams
6

Sie können einen regulären Ausdruck immer als Zeichenfolge angeben, d. H. "ReGeX" + testVar + "ReGeX" .Möglicherweise müssen Sie einige Zeichen in Ihrer Zeichenfolge maskieren (z. B. doppelte Anführungszeichen), aber in den meisten Fällen ist dies gleichwertig.

Sie können den RegExpKonstruktor auch zum Übergeben von Flags verwenden ( siehe Dokumentation ).

Nikita Rybak
quelle
3

Sie können reguläre Ausdrücke in JS auf zwei Arten erstellen:

  1. Literal für reguläre Ausdrücke verwenden - /ab{2}/g
  2. Verwenden des Konstruktors für reguläre Ausdrücke - new RegExp("ab{2}", "g").

Literale für reguläre Ausdrücke sind konstant und können nicht mit Variablen verwendet werden. Dies könnte mit dem Konstruktor erreicht werden. Die Struktur des RegEx-Konstruktors ist

new RegExp(regularExpressionString, modifiersString)

Sie können Variablen als Teil des regulären Ausdrucks einbetten. Beispielsweise,

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

Dies passt zu jedem Erscheinungsbild des Musters cdcdcd.

Ben Carp
quelle
2

Hier ist eine ziemlich nutzlose Funktion, die Werte zurückgibt, die von bestimmten Zeichen umbrochen werden. :) :)

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
quelle
2

akzeptierte Antwort funktioniert bei mir nicht und folgt nicht MDN-Beispielen

Siehe den Abschnitt 'Beschreibung' im obigen Link

Ich würde mit folgendem gehen, es funktioniert für mich:

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

// that makes dynamicRegExp = /findMe/gi
Timothy Mitchell
quelle
1
Es funktioniert noch. Das Problem ist, dass 'ReGeX' + testVar + 'ReGeX' die Lösung verwirrend macht. Das Hinzufügen eines tatsächlichen Beispiels würde meiner Meinung nach die Dinge klären. var testVar = '321'; var regex = new RegExp ("[" + testVar + "] {2}", "g"); // über Äquivalent zu / [321] {2} / g
HelloWorldPeace
1

Es ist nur erforderlich, zuerst die Zeichenfolgenvariable vorzubereiten und sie dann in RegEx zu konvertieren.

beispielsweise:

Sie hinzufügen möchten minLengthund MaxLengthmit den Variablen zu 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
}

jetzt, wenn Sie den Wert von MaxLengthoder ändernMinLength ändern, ändert sich dies in allen RegExs.

Ich hoffe, nützlich zu sein. Tut mir auch leid wegen meinem Englisch.

Abbas Habibnejad
quelle