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

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

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

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

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

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

30.01.2009 00:11:05
Обратите внимание, что в настоящее время мы работаем над добавлением этой функции в JavaScript, если у вас есть мнение по этому поводу, присоединяйтесь к обсуждению.
Benjamin Gruenbaum 23.06.2015 11:38:11
20 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

"mystring".replace(re, "newstring");
1805
17.12.2016 09:53:26
Если вам нужно использовать такое выражение , как /\/word\:\w*$/, убедитесь , чтобы избежать ваши обратные слэши: new RegExp( '\\/word\\:\\w*$' ).
Jonathan Swinney 9.11.2010 23:04:27
@gravityboy Вы можете сделать ('' + myNumber) .replace (/ 10 / g, 'a') или, если вы хотите шестнадцатеричные числа, вы можете сделать parseInt ('' + myNumber, 16) для преобразования в шестнадцатеричное из десятичного числа.
Eric Wendelin 21.06.2011 15:19:55
Вопрос предполагает, что RegEx используется только для постоянной замены строки. Так что это неправильный ответ, так как он потерпит неудачу, если строка содержит метасимволы RegEx. Грустно, что за это высоко проголосуют, будет много головных болей ...
dronus 12.02.2014 20:32:52
Пример передачи переменной мог бы сделать это хорошим ответом. Я все еще борюсь после прочтения этого.
Goose 5.06.2015 18:44:26
@JonathanSwinney: /не имеет особого значения, если вы создаете регулярное выражение из строки, поэтому вам не нужно избегать его. /\/word\:\w*$/должно бытьnew RegExp('/word\\:\\w*$')
Dávid Horváth 11.01.2017 13:52:18
this.replace( new RegExp( replaceThis, 'g' ), withThis );
21
16.01.2012 16:22:43
Мне нравится этот ответ, так как он не создает дополнительную (и бессмысленную) переменную.
Wick 4.04.2019 15:20:13

Эта:

var txt=new RegExp(pattern,attributes);

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

var txt=/pattern/attributes;

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

31
30.01.2009 00:19:19
да, но в первом примере он использует patternкак переменную, во 2-м - как строку
vladkras 9.07.2013 04:16:21

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

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

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

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Это связано с тем, что, хотя "."это строка типа String, в конструкторе 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".

209
19.06.2012 08:15:44
Вы знаете, что первый параметр для замены может быть обычной строкой и не должен быть регулярным выражением? str1 = "."; alert («сопоставление с образцом». replace (str1, «string»));
some 30.01.2009 10:31:05
@ некоторые: конечно. Это потому, что приведенный выше пример тривиален. Когда вам нужно найти или заменить шаблон, объединенный с обычной строкой, сделайте, например, str.match (new RegExp ("https?: //" + RegExp.escape (myDomainName)). Это раздражает, что функция escape не встроен.
Gracenotes 30.01.2009 19:57:58
(продолжение) Плюс, очевидно, Дж. К. Граббсу потребовалась глобальная замена; реализация глобальной замены с String.replace (String, String) может быть медленной для большого ввода. Я просто говорю, что два верхних решения содержат ошибки и неожиданно потерпят неудачу при определенных входных данных.
Gracenotes 30.01.2009 20:00:09
developer.mozilla.org/en-US/docs/JavaScript/Guide/… предлагает аналогичную функцию, но они исключают -и включают =!:/.
chbrown 15.12.2012 21:12:50
Правильный термин «побег», а не «цитата». Просто кстати.
Lawrence Dol 4.12.2015 05:19:40

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

3
23.05.2017 12:10:26

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

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

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

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

115
30.01.2018 11:45:13
И вы измерили, что это быстрее, чем регулярное выражение?
Mitar 10.04.2013 03:12:06
Это кажется предпочтительным, особенно когда необходимо сопоставить специальные символы регулярного выражения, такие как '.'
Krease 24.04.2013 18:41:42
Хм ... Не разделяет также и RegExp; если так, разве это не вызовет ту же проблему? В любом случае ... .split (). Join () может быть медленнее на некоторых платформах, потому что это две операции, тогда как .replace () - одна операция и может быть оптимизирована.
user1985657 12.06.2013 22:47:12
@ PacMan--: оба splitи replaceмогут принимать либо строку, либо RegExpобъект. Проблема, которая replaceимеет это split, состоит в том, что когда вы используете строку, вы получаете только одну замену.
bobince 13.06.2013 09:05:24
Wagner da Silva 21.02.2018 16:42:39
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Тест с этим инструментом

9
1.02.2009 09:28:54

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

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
34
9.05.2015 17:48:28

Вот еще одна замена 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;
    };
4
8.05.2013 10:30:36

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

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
5.06.2013 04:38:14

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

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

Вы всегда можете использовать 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
16.08.2013 19:53:34
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("]", ">"))
5
20.08.2013 12:35:29

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

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

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

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]"
14
21.08.2019 13:33:48

И версия ответа Стивена Пенни, написанная coffeescript, поскольку это # ​​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!"
4
29.10.2015 15:49:09
почему понизить? Coffeescript -IS- Javascript со своим собственным специфическим синтаксисом.
keen 26.08.2015 15:53:22
robot.name=hubotэто не JavaScript
codepleb 31.01.2020 14:14:10

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

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

То, что я реализовал, - это взятие значения из текстового поля, которое вы хотите заменить, а другое - текстовое поле «заменить на», получение значения из текстового поля в переменной и присвоение переменной значения 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 кнопки, вы можете поместить это в функцию для вызова.

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

1
12.07.2018 06:56:26
Ваша переменная replace_with будет содержать элемент DOM, а не само значение
Ben Taliadoros 27.10.2017 14:26:48

Если вы хотите получить ВСЕ вхождения ( 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.
35
13.06.2018 02:52:17
благодарю вас! (afaict, ваш единственный ответ явно с rxинтерполяцией в стиле Emacs / , через строки шаблонов.)
sam boosalis 8.04.2020 03:30:38

Ни один из этих ответов не был понятен мне. В конце концов я нашел хорошее объяснение на 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="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>

0
18.10.2018 18:37:43
Вы перезаписываете переменную замыкания, здесь не нужно использовать var. Кроме того, если вы пройдете \bили \1он сломается.
CyberAP 6.11.2018 19:00:07

Для множественной замены без регулярных выражений я пошел со следующим:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

Важная часть решения была найдена здесь

0
24.11.2019 01:52:17

Эта функция, вызывающая себя, будет перебирать элементы replacerItems с использованием индекса и глобально изменять replacerItems [index] в строке при каждом проходе.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'
1
16.12.2019 17:24:35