Використовуйте динамічний (змінний) рядок як шаблон регулярного виразу в JavaScript


101

Я хочу додати (змінний) тег до значень із регулярним виразом, шаблон працює добре з PHP, але у мене виникають проблеми з його реалізацією в JavaScript.

Шаблон ( valueє змінною):

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

Я уникнув зворотних скісних рисок:

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

Але це, здається, не правильно, я записав шаблон і його саме те, яким він повинен бути. Будь-які ідеї?


Це valueзмінна?
Догберт

Відповіді:


173

Щоб створити регулярний вираз із рядка, вам потрібно використовувати об'єкт JavaScriptRegExp .

Якщо ви хочете , щоб відповідати / замінити більш ніж один раз, то ви повинні додати в g(глобальний матч) прапор . Ось приклад:

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 тут.


У загальному випадку, використовуйте рядок, перш ніж використовувати як регулярний вираз:

Не кожен рядок є дійсним регулярним виразом, проте: є деякі спеціальні символи, такі як (або [. Щоб вирішити цю проблему, просто уникніть рядка, перш ніж перетворити його на регулярний вираз. Функція корисності для цього наведена у зразку нижче:

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 тут.



Примітка: регулярний вираз у питанні використовує sмодифікатор, якого на момент запитання не існувало , але існує - прапор / модифікатор s( крапка ) у JavaScript - сьогодні .


2
це чудово і найкращий приклад, який я знайшов на сьогоднішній день використання динамічної змінної в регулярному виразі, дякую!
Eolis

1
На 2019 рік є s модифікатор, див. Ще раз посилання MDN у примітці до відповіді.
Nickensoul

@Nickensoul Добре помічено! Дякуємо за голови!
acdcjunior

нехай idr = новий RegExp (змінна + "$"); Table.find ({field: new RegExp (idr, 'i')}) Мені сподобалось це. На ура
Уткарш,

12

Якщо ви намагаєтесь використати значення змінної у виразі, ви повинні використовувати "конструктор" RegExp.

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

6

Вам не потрібно "визначати регулярний вираз, тому просто:

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

Якщо valueє змінною, і ви хочете динамічний регулярний вираз, тоді ви не можете використовувати цей запис; використовувати альтернативні позначення.

String.replace також приймає рядки як вхідні дані, так що ви можете це зробити "fox".replace("fox", "bear");

Альтернатива:

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

Майте на увазі, що якщо вони valueмістять регулярні вирази, символи типу (, [і ?вам потрібно буде їх уникнути.


2
Перший варіант не спрацював би, якщо не шукати рядок "значення"
mothmonsterman

@happytimeharry Здається, існує конфлікт між двома регулярними термінами, які він розмістив.
Halcyon

@Fritz van Campen здається, що метою шаблону, наведеного на прикладі з його javascript, було використання змінної
mothmonsterman

та сама проблема тут, здається, щось не так із прапором "is": "Uncaught SyntaxError: Недійсні прапори, що надходять до конструктора RegExp 'is'"
Borstenhorst

прапори для конструктора RegExp потрібно розділити. Але все ще регулярний вираз не працює.
Borstenhorst

5

Я знайшов цю тему корисною - тому подумав, що додам відповідь до власної проблеми.

Я хотів відредагувати файл конфігурації бази даних (datastax cassandra) із програми вузла в javascript, а для одного з параметрів у файлі мені знадобилося збіг у рядку, а потім замінити рядок, що слідує за ним.

Це було моє рішення.

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

Після запуску він змінить існуючий параметр каталогу даних на новий:

конфігураційний файл перед:

data_file_directories:  
   - /var/lib/cassandra/data

конфігураційний файл після:

data_file_directories:  
- /mnt/cassandra/data

4

Я виявив, що мені довелося подвійно скосити \ b, щоб він працював. Наприклад, щоб видалити слова "1x" із рядка за допомогою змінної, мені потрібно було використовувати:

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

Працював у мене. Дякую,
Правін Бапкар

1

Набагато простіший спосіб: використовуйте шаблонні літерали.

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/

Сподіваюся, це допомагає

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.