Wie verwendet man eine Variable in einem regulären Ausdruck?

1379

Ich möchte eine String.replaceAll()Methode in JavaScript erstellen und denke, dass die Verwendung eines regulären Ausdrucks der knappste Weg wäre, dies zu tun. Ich kann jedoch nicht herausfinden, wie eine Variable an einen regulären Ausdruck übergeben wird. Ich kann dies bereits tun, wodurch alle Instanzen von "B"durch ersetzt werden "A".

"ABABAB".replace(/B/g, "A");

Aber ich möchte so etwas tun:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

Aber dies ersetzt natürlich nur den Text. "replaceThis"Wie übergebe ich diese Variable an meine Regex-Zeichenfolge?

JC Grubbs
quelle
9
Beachten Sie, dass wir derzeit daran arbeiten, diese Funktionalität zu JavaScript hinzuzufügen. Wenn Sie eine Meinung dazu haben, nehmen Sie bitte an der Diskussion teil.
Benjamin Gruenbaum

Antworten:

1842

Anstatt die /regex/gSyntax zu verwenden, können Sie ein neues RegExp- Objekt erstellen :

var replace = "regex";
var re = new RegExp(replace,"g");

Auf diese Weise können Sie Regex-Objekte dynamisch erstellen. Dann wirst du tun:

"mystring".replace(re, "newstring");
Eric Wendelin
quelle
272
Wenn Sie einen Ausdruck wie verwenden müssen /\/word\:\w*$/, müssen Sie Ihre Backslashes vermeiden : new RegExp( '\\/word\\:\\w*$' ).
Jonathan Swinney
2
@gravityboy Sie können ('' + myNumber) .replace (/ 10 / g, 'a') ausführen oder wenn Sie Hex-Zahlen möchten, können Sie parseInt ('' + myNumber, 16) ausführen, um von Dezimal in Hex zu konvertieren.
Eric Wendelin
29
Die Frage legt nahe, dass RegEx nur zum Ersetzen einer konstanten Zeichenfolge verwendet wird. Diese Antwort ist also falsch, da sie fehlschlagen würde, wenn die Zeichenfolge RegEx-Metazeichen enthält. Traurig, dass es so hoch gewählt wird, wird viele Kopfschmerzen machen ...
Dronus
16
Ein Beispiel für die Übergabe einer Variablen wäre eine gute Antwort. Ich habe immer noch Probleme, nachdem ich das gelesen habe.
Gans
3
@JonathanSwinney: /hat keine besondere Bedeutung, wenn Sie Regex aus einem String erstellen , sodass Sie ihm nicht entkommen müssen. /\/word\:\w*$/sollte seinnew RegExp('/word\\:\\w*$')
Dávid Horváth
211

Wie Eric Wendelin erwähnte, können Sie so etwas tun:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

Dies ergibt "regex matching .". Es wird jedoch fehlschlagen, wenn str1 ist ".". Sie würden erwarten, dass das Ergebnis "pattern matching regex"den Punkt durch ersetzt "regex", aber es wird sich herausstellen, dass ...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Dies liegt daran, dass "."der RegExp-Konstruktor , obwohl es sich um eine Zeichenfolge handelt, immer noch als regulärer Ausdruck interpretiert wird, dh jedes Zeichen ohne Zeilenumbruch, dh jedes Zeichen in der Zeichenfolge. Zu diesem Zweck kann die folgende Funktion nützlich sein:

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

Dann können Sie tun:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

Nachgeben "pattern matching regex".

Gracenotes
quelle
4
Sie wissen, dass der erste zu ersetzende Parameter eine normale Zeichenfolge sein kann und kein regulärer Ausdruck sein muss? str1 = "."; alert ("Mustervergleich". replace (str1, "string"));
einige
@some: natürlich. Das liegt daran, dass das obige Beispiel trivial ist. Wenn Sie nach einem Muster suchen oder es ersetzen müssen, das mit einer regulären Zeichenfolge kombiniert ist, führen Sie beispielsweise str.match (neues RegExp ("https ?: //" + RegExp.escape (myDomainName)) "aus. Es ist ärgerlich, dass die Escape-Funktion aktiviert ist nicht eingebaut.
Gracenotes
(Fortsetzung) Außerdem erforderte JC Grubbs offenbar einen globalen Ersatz. Das Implementieren eines globalen Ersetzens durch String.replace (String, String) kann bei großen Eingaben langsam sein. Ich sage nur, die beiden Top-Lösungen sind fehlerhaft und schlagen bei bestimmten Eingaben unerwartet fehl.
Gracenotes
4
developer.mozilla.org/en-US/docs/JavaScript/Guide/… bietet eine ähnliche Funktion, die jedoch ausgeschlossen -und eingeschlossen werden =!:/.
chbrown
8
Der richtige Begriff ist "Flucht", nicht "Zitat". Nur übrigens.
Lawrence Dol
118

"ABABAB".replace(/B/g, "A");

Wie immer: Verwenden Sie keinen regulären Ausdruck, es sei denn, Sie müssen. Für ein einfaches Ersetzen von Zeichenfolgen lautet die Redewendung:

'ABABAB'.split('B').join('A')

Dann müssen Sie sich keine Gedanken über die in Gracenotes 'Antwort erwähnten Zitierprobleme machen.

Bobince
quelle
11
Und haben Sie gemessen, dass dies schneller als Regex ist?
Mitar
3
Dies scheint vorzuziehen, insbesondere wenn spezielle Regex-Zeichen wie '.'
Krease
1
Ähm ... Split nimmt nicht auch einen RegExp; Wenn ja, würde es nicht das gleiche Problem verursachen? Wie auch immer ... .split (). Join () kann auf einigen Plattformen langsamer sein, da es sich um zwei Operationen handelt, während .replace () eine Operation ist und möglicherweise optimiert wird.
5
@ PacMan--: beides splitund replacekann entweder einen String oder ein RegExpObjekt aufnehmen. Das Problem, replacedas splitdies nicht hat, ist, dass Sie bei Verwendung einer Zeichenfolge nur einen einzigen Ersatz erhalten.
Bobince
1
Benchmark hier: jsperf.com/replace-vs-split-join-vs-replaceall/23
Wagner da Silva
38

Wenn Sie ALLE Vorkommen erhalten möchten ( g), achten Sie nicht auf Groß- und Kleinschreibung ( i) und verwenden Sie Grenzen, damit es sich nicht um ein Wort in einem anderen Wort handelt ( \\b):

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

Beispiel:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.
JBallin
quelle
Vielen Dank! (Afaict, Ihre ist die einzige Antwort, die explizit mit Emacs / rx-Stil-Interpolation über Template-Strings beantwortet wird.)
sam boosalis
34

Für alle, die Variablen mit der Match- Methode verwenden möchten, hat dies bei mir funktioniert

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
Steven Penny
quelle
31

Diese:

var txt=new RegExp(pattern,attributes);

ist gleichbedeutend damit:

var txt=/pattern/attributes;

Siehe http://www.w3schools.com/jsref/jsref_obj_regexp.asp .

Jeremy Ruten
quelle
20
Ja, aber im ersten Beispiel wird es patternals Variable verwendet, im zweiten als String
vladkras
20
this.replace( new RegExp( replaceThis, 'g' ), withThis );
Tvanfosson
quelle
Ich mag diese Antwort, da sie keine zusätzliche (& sinnlose) Variable erzeugt.
Wick
14

Sie möchten den regulären Ausdruck dynamisch erstellen, und die richtige Lösung besteht darin, den new RegExp(string)Konstruktor zu verwenden. Damit der Konstruktor Sonderzeichen wörtlich behandeln kann, müssen Sie ihnen entkommen. Das Widget für die automatische Vervollständigung der jQuery-Benutzeroberfläche verfügt über eine integrierte Funktion mit dem Namen $.ui.autocomplete.escapeRegex:

[...] können Sie die eingebaute $.ui.autocomplete.escapeRegexFunktion nutzen. Es wird ein einzelnes String-Argument benötigt, um alle Regex-Zeichen zu maskieren, sodass das Ergebnis sicher weitergegeben werden kann new RegExp().

Wenn Sie die jQuery-Benutzeroberfläche verwenden, können Sie diese Funktion verwenden oder ihre Definition aus der Quelle kopieren :

function escapeRegex( value ) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

Und benutze es so:

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"
Salman A.
quelle
9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Testen Sie mit diesem Tool

unigogo
quelle
5
String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}

Testen Sie es wie:

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))
MetalGodwin
quelle
4

Hier ist eine weitere Implementierung von replaceAll:

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };
scripto
quelle
4

Und die Coffeescript-Version von Steven Pennys Antwort, da dies das zweite Google-Ergebnis ist ... auch wenn Kaffee nur Javascript ist und viele Zeichen entfernt wurden ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

und in meinem speziellen Fall

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"
daran interessiert
quelle
Warum eine Ablehnung? coffeescript -IS- Javascript mit eigener Syntax.
scharf
robot.name=hubotist kein Javascript.
Codepleb
3

Während Sie dynamisch erstellte RegExps erstellen können (wie in den anderen Antworten auf diese Frage angegeben), werde ich meinen Kommentar aus einem ähnlichen Beitrag wiederholen : Die funktionale Form von String.replace () ist äußerst nützlich und reduziert in vielen Fällen den Bedarf an dynamisch erstellte RegExp-Objekte. (Dies ist eine Art Schmerz, da Sie die Eingabe in den RegExp-Konstruktor als Zeichenfolge ausdrücken müssen, anstatt das Literalformat Schrägstriche / [AZ] + / regexp zu verwenden.)

Jason S.
quelle
3

Um mein Bedürfnis zu befriedigen, eine Variable / einen Alias ​​/ eine Funktion in einen regulären Ausdruck einzufügen, habe ich mir Folgendes ausgedacht:

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

Dabei ist 'oldre' der ursprüngliche reguläre Ausdruck, in den ich eine Variable einfügen möchte, 'xx' der Platzhalter für diese Variable / diesen Alias ​​/ diese Funktion und 'yy' der tatsächliche Variablenname, Alias ​​oder die eigentliche Funktion.

Alex Li
quelle
2

Sie können dies verwenden, wenn $ 1 nicht mit Ihnen zusammenarbeitet

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");
Fareed Alnamrouti
quelle
1

Sie können immer indexOfwiederholt verwenden:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

Dies geht nicht in eine Endlosschleife, wenn der Ersatz die Übereinstimmung enthält.

Ry-
quelle
1

Ihre Lösung ist hier:

Übergeben Sie eine Variable an den regulären Ausdruck.

Das, was ich implementiert habe, besteht darin, den Wert aus einem Textfeld zu übernehmen, das Sie ersetzen möchten, und ein anderes ist das Textfeld "Ersetzen durch", den Wert aus dem Textfeld in einer Variablen abzurufen und die Variable auf RegExp zu setzen Funktion zum weiteren Ersetzen. In meinem Fall verwende ich Jquery. Sie können dies auch nur mit JavaScript tun.

JavaScript-Code:

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
  var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.

  var sRegExInput = new RegExp(replace, "g");    
  $("body").children().each(function() {
    $(this).html($(this).html().replace(sRegExInput,replace_with));
  });

Dieser Code befindet sich beim Onclick-Ereignis einer Schaltfläche. Sie können ihn in eine aufzurufende Funktion einfügen.

Jetzt können Sie eine Variable in der Ersetzungsfunktion übergeben.

Ajit Hogade
quelle
Ihre Variable replace_with enthält das DOM-Element und nicht den Wert selbst
Ben Taliadoros,
1

Diese selbstaufrufende Funktion iteriert mithilfe eines Index über replaceerItems und ändert mit jedem Durchgang replaceerItems [index] global für die Zeichenfolge.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'

quelle
0

Keine dieser Antworten war mir klar. Ich fand schließlich eine gute Erklärung unter http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-function-of-javascript/

Die einfache Antwort lautet:

var search_term = new RegExp(search_term, "g");    
text = text.replace(search_term, replace_term);

Zum Beispiel:

$("button").click(function() {
  Find_and_replace("Lorem", "Chocolate");
  Find_and_replace("ipsum", "ice-cream");
});

function Find_and_replace(search_term, replace_term) {
  text = $("textbox").html();
  var search_term = new RegExp(search_term, "g");
  text = text.replace(search_term, replace_term);
  $("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>

Paul Chris Jones
quelle
1
Sie überschreiben eine Abschlussvariable, die Sie hier nicht verwenden müssen var. Auch wenn Sie passen \boder \1es brechen würde.
CyberAP
0

Für mehrere Ersetzungen ohne reguläre Ausdrücke habe ich Folgendes gewählt:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

Der wichtige Teil der Lösung wurde hier gefunden

John Shearing
quelle