Użyj dynamicznego (zmiennej) ciągu znaków jako wzorca wyrażenia regularnego w JavaScript


109

Chcę dodać tag (zmienny) do wartości z wyrażeniem regularnym, wzorzec działa dobrze z PHP, ale mam problemy z implementacją go w JavaScript.

Wzorzec to ( valuejest zmienną):

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

Uniknąłem ukośników:

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

Ale wydaje się, że to nie jest w porządku, zarejestrowałem wzór i dokładnie tak, jak powinien. Jakieś pomysły?


Czy valuejest zmienną?
Dogbert

Odpowiedzi:


188

Aby utworzyć wyrażenie regularne z łańcucha, musisz użyć obiektu JavaScriptRegExp .

Jeśli chcesz, aby dopasować / wymienić więcej niż jeden raz, to musi dodać do gflag (Global mecz) . Oto przykład:

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.

Demo JSFiddle tutaj.


W ogólnym przypadku, przed użyciem jako wyrażenia regularnego, przed użyciem znaku ucieczki:

Jednak nie każdy ciąg jest prawidłowym wyrażeniem regularnym: jest kilka specyficznych znaków, takich jak (lub [. Aby obejść ten problem, po prostu usuń ciąg znaków przed przekształceniem go w wyrażenie regularne. Funkcja narzędziowa do tego znajduje się w poniższym przykładzie:

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.

Demo JSFiddle tutaj.



Uwaga: wyrażenie regularne w pytaniu używa smodyfikatora, który nie istniał w momencie zadawania pytania, ale istnieje - flaga / modyfikator s( dotall ) w JavaScript - obecnie .


2
to jest świetny i najlepszy przykład, jaki do tej pory znalazłem, wykorzystania zmiennej dynamicznej w wyrażeniu regularnym, dzięki!
Eolis

1
Dla 2019 jest s modyfikator, zobacz ponownie link MDN w notatce odpowiedzi.
Nickensoul,

@Nickensoul Well spotted! Dzięki za ostrzeżenie!
acdcjunior

let idr = new RegExp (zmienna + "$"); Table.find ({field: new RegExp (idr, 'i')}) Zrobiłem to. Twoje zdrowie.
Utkarsh

14

Jeśli próbujesz użyć wartości zmiennej w wyrażeniu, musisz użyć „konstruktora” RegExp.

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

7

Nie musisz "definiować wyrażenia regularnego, więc po prostu:

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

Jeśli valuejest zmienną i chcesz dynamicznego wyrażenia regularnego, nie możesz użyć tej notacji; użyj notacji alternatywnej.

String.replace akceptuje również ciągi znaków jako dane wejściowe, więc możesz to zrobić "fox".replace("fox", "bear");

Alternatywny:

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

Pamiętaj, że jeśli valuezawiera wyrażenia regularne, takie jak (, [i ?będziesz musiał przed nimi uciec.


2
Pierwsza opcja nie zadziałałaby, gdyby nie wyszukanie ciągu znaków „wartość”
mothmonsterman

@happytimeharry Wydaje się, że występuje konflikt między dwoma opublikowanymi przez niego wyrażeniami regularnymi.
Halcyon

@Fritz van Campen wydaje się, że intencją wzorca, biorąc pod uwagę przykład z jego javascript, było użycie zmiennej
mothmonsterman

ten sam problem, wydaje się, że coś jest nie tak z flagą "is": "Uncaught SyntaxError: Niepoprawne flagi dostarczone do konstruktora RegExp 'to'"
Borstenhorst

flagi dla konstruktora RegExp muszą zostać rozdzielone. Jednak regex nadal nie działa.
Borstenhorst

5

Ten wątek okazał się przydatny - pomyślałem więc, że dodam odpowiedź do własnego problemu.

Chciałem edytować plik konfiguracyjny bazy danych (datastax cassandra) z aplikacji węzła w javascript i dla jednego z ustawień w pliku musiałem dopasować do ciągu, a następnie zastąpić linię po nim.

To było moje rozwiązanie.

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

Po uruchomieniu zmieni istniejące ustawienie katalogu danych na nowe:

config przed:

data_file_directories:  
   - /var/lib/cassandra/data

config po:

data_file_directories:  
- /mnt/cassandra/data

4

Okazało się, że muszę dwukrotnie przyciąć \ b, aby działał. Na przykład, aby usunąć słowa „1x” z ciągu za pomocą zmiennej, musiałem użyć:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");

Pracował dla mnie. Dzięki,
Pravin Bhapkar,

1

O wiele prostszy sposób: użyj literałów szablonów.

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

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/

Mam nadzieję że to pomoże

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.