Как вы используете переменную в регулярном выражении?

1067

Я хотел бы создать метод String.replaceAll() в JavaScript, и я думаю, что использование RegEx было бы самым сложным способом сделать это. Однако я не могу понять, как передать переменную в RegEx. Я могу сделать это уже, что заменит все экземпляры "B" на "A".

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

Но я хочу сделать что-то вроде этого:

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

Но, очевидно, это заменит только текст "replaceThis"... так как передать эту переменную в мою строку RegEx?

Теги:

19 ответов

1424
Лучший ответ

Вместо синтаксиса /regex/g вы можете создать новый объект RegExp:

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

Вы можете динамически создавать объекты регулярных выражений таким образом. Затем вы выполните:

"mystring".replace(re, "newstring");
  • 234
    Если вам нужно использовать выражение типа /\/word\:\w*$/ , обязательно избегайте обратной косой черты: new RegExp( '\\/word\\:\\w*$' ) .
  • 1
    wendelin Если у меня есть строка, и я хочу заменить все «10» на «a», как мне сделать это с вашей функцией?
Показать ещё 15 комментариев
177

Как упоминал Эрик Венделин, вы можете сделать что-то вроде этого:

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

Это дает "regex matching .". Однако он будет терпеть неудачу, если str1 ".". Вы ожидаете, что результат будет "pattern matching regex", заменив период на "regex", но он окажется...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Это потому, что, хотя "." является строкой, в конструкторе RegExp он по-прежнему интерпретируется как регулярное выражение, что означает любой символ нестрочного разрыва, означающий каждый символ в строке. Для этой цели может быть полезной следующая функция:

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

Затем вы можете сделать:

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

дает "pattern matching regex".

  • 4
    Вы знаете, что первый параметр для замены может быть нормальной строкой и не должен быть регулярным выражением? str1 = "."; alert («сопоставление с образцом». replace (str1, «string»));
  • 0
    @ некоторые: конечно. Это потому, что приведенный выше пример тривиален. Когда вам нужно найти или заменить шаблон в сочетании с обычной строкой, сделайте, например, str.match (new RegExp ("https?: //" + RegExp.escape (myDomainName)). Это раздражает, что функция escape не встроенный
Показать ещё 5 комментариев
94

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

Как всегда: не используйте регулярное выражение, если вам не нужно. Для простой замены строки идиома:

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

Тогда вам не нужно беспокоиться о цитировании вопросов, упомянутых в ответе Gracenotes.

  • 9
    И вы измерили, что это быстрее, чем регулярное выражение?
  • 2
    Это кажется предпочтительным, особенно когда необходимо сопоставить специальные символы регулярного выражения, такие как '.'
Показать ещё 6 комментариев
30

Для тех, кто хочет использовать переменную с методом match, это сработало для меня

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
  • 0
    Спасибо, вы мне очень помогли
26

Это:

var txt=new RegExp(pattern,attributes);

эквивалентно этому:

var txt=/pattern/attributes;

См. http://www.w3schools.com/jsref/jsref_obj_regexp.asp.

  • 15
    да, но в первом примере он использует pattern как переменную, во 2-м как строку
  • 2
    Я на самом деле считаю, что это самый ясный ответ.
15
this.replace( new RegExp( replaceThis, 'g' ), withThis );
10

Если вы хотите получить ВСЕ вхождения (g), нечувствительны к регистру (i) и используйте границы, чтобы это не было слово в другом слове (\\b):

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

Пример:

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.
9

Вы хотите динамически строить регулярное выражение, и для этого правильным решением является использование new RegExp(string). Чтобы конструктор обрабатывал специальные символы буквально, вы должны избегать их. В $.ui.autocomplete.escapeRegex автозаполнения jQuery UI есть встроенная функция с именем $.ui.autocomplete.escapeRegex:

[...] вы можете использовать встроенную функцию $.ui.autocomplete.escapeRegex. Он будет принимать один строковый аргумент и избежать всех символов регулярных выражений, что сделает результат безопасным для перехода к new RegExp().

Если вы используете jQuery UI, вы можете использовать эту функцию или скопировать ее определение из источника:

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

И используйте его вот так:

"[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]"
9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Протестируйте с помощью tool

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

Протестируйте его так:

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

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

Здесь другая реализация 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;
    };
3

И версия кофейня Стивена Пенни ответит, так как это результат №2 google.... даже если кофе - это просто javascript с большим количеством символов, удаленных...;)

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

и в моем конкретном случае

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"
  • 0
    почему понизить? coffeescript -IS- javascript со своим собственным специфическим синтаксисом.
3

Чтобы удовлетворить мою потребность вставить переменную/псевдоним/функцию в регулярное выражение, вот что я придумал:

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

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

где "oldre" - это исходное регулярное выражение, которое я хочу вставить в переменную, "xx" является заполнителем этой переменной/псевдонима/функции, и 'yy' - это фактическое имя переменной, псевдоним или функция.

3

Пока вы можете создать динамически созданный RegExp (как и другие ответы на этот вопрос), я отправлю комментарий из аналогичного сообщения: Функциональная форма String.replace() чрезвычайно полезен и во многих случаях уменьшает потребность в динамически создаваемых объектах RegExp. (которые являются своего рода болью, потому что вам нужно выразить ввод конструктору RegExp как строку, а не использовать листы слэшей /[A-Z] +/regexp)

1

Ваше решение здесь:

Передайте переменную в регулярное выражение.

Тот, который я реализовал, - это значение, полученное из текстового поля, которое вы хотите заменить, а другое - текстовым полем "заменить на", получая значение из текстового поля в переменной и устанавливая переменную в RegExp для дальнейшей замены. В моем случае я использую JQuery, вы также можете сделать это только с помощью JavaScript.

Код JavaScript:

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

Этот код находится в событии Onclick кнопки, вы можете поместить его в функцию для вызова.

Итак, теперь вы можете передать переменную взамен функции.

  • 0
    Ваша переменная replace_with будет содержать элемент DOM, а не само значение
1

Вы всегда можете использовать indexOf несколько раз:

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

Это не входит в бесконечный цикл, когда замена содержит совпадение.

1

Вы можете использовать это, если $1 не работает с вами

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

Ни один из этих ответов не был понятен мне. В конце концов я нашел хорошее объяснение на http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-function-of-javascript/

Простой ответ:

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

Например:

$("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="/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>
  • 0
    Вы перезаписываете переменную замыкания, нет необходимости использовать var здесь. Кроме того, если вы передадите \b или \1 он сломается.
0

Для чрезвычайно простых запросов:

// dynamic query
const query = 'lo' // lets say its coming from an input field

// matching it with something
const doestItMatch = "Hello World!".indexOf(query) >= 0

// results
console.log(doesItMatch) // boolean result - true or false

Рабочий пример: filtering a list of items

// I can work with it in an array of "items" to filter the array
// the "query" variable is dynamic
const filteredItems = allItems.filter(item => item.text.indexOf(query) >= 0)

console.log(filteredItems) // will have an array of items that have a "text" key with a value that has the "query" somewhere it it.

Удачи.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню