2013-07-26 20 views
33

Chcę dodać (zmienną) tag do wartości z regex, wzór działa dobrze z PHP, ale mam problemy z zaimplementowaniem go w JavaScript.Użyj łańcucha dynamicznego (zmiennego) jako wzorca regex w JavaScript

Wzór jest (value jest zmienna):

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

Uciekłem ukośniki:

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

Ale to nie wydają się być w porządku, ja zalogowany wzór i jej dokładnie to, co powinno być. Jakieś pomysły?

+0

Czy "wartość" jest zmienną? – Dogbert

Odpowiedz

77

Aby utworzyć regex jako ciąg, trzeba użyć JavaScript's RegExp object.

Możesz również dopasować/zastąpić więcej niż jeden raz. W takim przypadku dodaj the g (global match) flag. 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. 

JSFiddle demo here.


W ogólnym przypadku, ucieczka ciąg przed użyciem jako regex:

Nie każdy ciąg jest prawidłowy regex, choć: istnieje kilka specjalnych znaków, takich jak ( lub [. Aby obejść ten problem, po prostu uciec ciąg przed przekształceniem go w regex. Funkcja narzędzie dla że idzie 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. 

JSFiddle demo here.


Dla konkretnej sprawy, zauważyć there is no s (dotall) flag/modifier in JavaScript. Tam, gdzie jest on dostępny, zwykle zmusza kropkę (.) do dopasowania do nowych linii.Oto możliwe rozwiązanie dla Twojej sprawy:

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

Wskazówka dodałem brakujący ' na koniec "<a href='#" + value +"'>".

See demo fiddle here. Możesz także wypróbować numer this solution using the "g" modifier.

+0

Dzięki, który działał – Borstenhorst

+1

to jest świetny i najlepszy przykład, jaki znalazłem do tej pory używania zmiennej dynamicznej w regex, dzięki! – Eolis

2

Nie trzeba się " zdefiniować wyrażenie regularne, więc po prostu:

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

Jeśli value jest zmienna i chcesz dynamiczne wyrażenie regularne to nie można korzystać z tego zapisu; użyj zapisu alternatywnego.

String.replace akceptuje również ciągi jak wejścia, więc można zrobić "fox".replace("fox", "bear");

Alternatywa:

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

Należy pamiętać, że jeśli value zawiera wyrażenia regularne znaki takie jak (, [ i ? trzeba będzie uciec im.

+1

Pierwsza opcja nie działałaby, gdyby nie szukanie ciągu "wartość" –

+0

@happytimeharry Wydaje się, że istnieje konflikt pomiędzy dwoma zamieszczonymi przez niego wyrażeń regularnych. – Halcyon

+0

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

8

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

Znalazłem ten wątek przydatny - więc pomyślałem, że dodam odpowiedź na mój własny problem.

Chciałem edytować plik konfiguracyjny bazy danych (datastax cassandra) z aplikacji węzła w javascript i dla jednego z ustawień w pliku, które musiałem dopasować na łańcuchu, a następnie zastąpić linię następującą 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, będzie to zmienić istniejące ustawienia katalogu danych na nowy:

plik konfiguracyjny przed:

data_file_directories: 
    - /var/lib/cassandra/data 

plik konfiguracyjny po:

data_file_directories: 
- /mnt/cassandra/data 
Powiązane problemy