Verwenden Sie eine dynamische (variable) Zeichenfolge als Regex-Muster in JavaScript

97

Ich möchte Werten mit Regex ein (variables) Tag hinzufügen. Das Muster funktioniert gut mit PHP, aber ich habe Probleme, es in JavaScript zu implementieren.

Das Muster ist ( valueist die Variable):

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

Ich bin den Backslashes entkommen:

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

Aber das scheint nicht richtig zu sein, ich habe das Muster protokolliert und es ist genau das, was es sein sollte. Irgendwelche Ideen?

Borstenhorst
quelle
Ist valueeine Variable?
Dogbert

Antworten:

167

Um den regulären Ausdruck aus einer Zeichenfolge zu erstellen, müssen Sie das JavaScript- RegExpObjekt verwenden .

Wenn Sie auch mehr als einmal übereinstimmen / ersetzen möchten, müssen Sie das gFlag (globale Übereinstimmung) hinzufügen . Hier ist ein Beispiel:

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.

JSFiddle-Demo hier.


Im allgemeinen Fall maskieren Sie die Zeichenfolge, bevor Sie sie als regulären Ausdruck verwenden:

Nicht jede Zeichenfolge ist jedoch ein gültiger regulärer Ausdruck: Es gibt einige spezielle Zeichen wie (oder [. Um dieses Problem zu umgehen, maskieren Sie einfach die Zeichenfolge, bevor Sie sie in einen regulären Ausdruck verwandeln. Eine Utility-Funktion dafür finden Sie im folgenden Beispiel:

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.

JSFiddle-Demo hier.



Hinweis: Der reguläre Ausdruck in der Frage verwendet den sModifikator, der zum Zeitpunkt der Frage noch nicht vorhanden war, aber heute existiert - ein s( dotall ) Flag / Modifikator in JavaScript .

acdcjunior
quelle
2
Das ist großartig und das beste Beispiel, das ich bisher für die Verwendung einer dynamischen Variablen in einem regulären Ausdruck gefunden habe, danke!
Eolis
1
Für 2019 gibt es einen s Modifikator, siehe erneut den MDN-Link in der Antwortnotiz.
Nickensoul
@ Nickensoul Gut entdeckt! Danke für die Warnung!
acdcjunior
let idr = new RegExp (Variable + "$"); Table.find ({field: new RegExp (idr, 'i')}) Das hat mir gefallen. Prost.
Utkarsh
12

Wenn Sie versuchen, einen Variablenwert im Ausdruck zu verwenden, müssen Sie den RegExp- "Konstruktor" verwenden.

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
Mottenmonsterman
quelle
6

Sie brauchen das nicht ", um einen regulären Ausdruck zu definieren, also nur:

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

Wenn valuees sich um eine Variable handelt und Sie einen dynamischen regulären Ausdruck wünschen, können Sie diese Notation nicht verwenden. Verwenden Sie die alternative Notation.

String.replace Akzeptiert auch Zeichenfolgen als Eingabe, sodass Sie dies tun können "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");

Beachten Sie, dass , wenn valuewie reguläre Ausdrücke Zeichen enthält (, [und ?Sie müssen sie entkommen.

Halcyon
quelle
1
Die erste Option würde nicht funktionieren, wenn nicht nach der Zeichenfolge "Wert"
gesucht wird
@happytimeharry Es scheint einen Konflikt zwischen den beiden regulären Ausdrücken zu geben, die er gepostet hat.
Halcyon
@Fritz van Campen es scheint, dass die Absicht des Musters, am Beispiel aus seinem Javascript gegeben, war, eine Variable zu verwenden
mothmonsterman
Das gleiche Problem hier, es scheint etwas mit dem "is" -Flag nicht zu stimmen: "Uncaught SyntaxError: Ungültige Flags, die an den RegExp-Konstruktor 'is' geliefert wurden"
Borstenhorst
Die Flags für den Konstruktor von RegExp müssen getrennt werden. Aber der Regex funktioniert immer noch nicht.
Borstenhorst
5

Ich fand diesen Thread nützlich - also dachte ich, ich würde die Antwort auf mein eigenes Problem hinzufügen.

Ich wollte eine Datenbankkonfigurationsdatei (datastax cassandra) aus einer Knotenanwendung in Javascript bearbeiten und für eine der Einstellungen in der Datei musste ich eine Zeichenfolge abgleichen und dann die darauf folgende Zeile ersetzen.

Das war meine Lösung.

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 );

Nach dem Ausführen wird die vorhandene Datenverzeichniseinstellung in die neue geändert:

Konfigurationsdatei vor:

data_file_directories:  
   - /var/lib/cassandra/data

Konfigurationsdatei nach:

data_file_directories:  
- /mnt/cassandra/data
JRD
quelle
4

Ich stellte fest, dass ich das \ b doppelt zerschneiden musste, damit es funktioniert. Um beispielsweise "1x" -Wörter mithilfe einer Variablen aus einer Zeichenfolge zu entfernen, musste ich Folgendes verwenden:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");
werden
quelle
Hat für mich gearbeitet. Danke,
Pravin Bhapkar
0
var string = "Hi welcome to stack overflow"
var toSearch = "stack"

//case insensitive search

var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'

https://jsfiddle.net/9f0mb6Lz/

Hoffe das hilft

Vinu
quelle
0

Viel einfacher: Verwenden Sie Vorlagenliterale.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Alec Donald Mather
quelle