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

Я хотел бы создать метод 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?

30 ответов

Решение

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

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

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

"mystring".replace(re, "newstring");

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

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",

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

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

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

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

Если вы хотите получить ВСЕ вхождения (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.

Это:

var txt=new RegExp(pattern,attributes);

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

var txt=/pattern/attributes;

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

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

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight
this.replace( new RegExp( replaceThis, 'g' ), withThis );

Вы хотите построить регулярное выражение динамически, и для этого правильным решением является использование new RegExp(string) конструктор. Чтобы конструктор обрабатывал специальные символы буквально, вы должны избегать их. В виджете автозаполнения пользовательского интерфейса jQuery есть встроенная функция $.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]"
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

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

Вы можете использовать строку как регулярное выражение, не забудьте использовать новый RegExp

пример:

      var yourFunction = new RegExp(
        '^-?\\d+(?:\\.\\d{0,' + yourVar + '})?'
      )
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("]", ">"))

И версия ответа Стивена Пенни, написанная 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!"

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

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' - фактическое имя переменной, псевдоним или функция.

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

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

Вот еще одна замена 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;
    };

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

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

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

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

Ни один из этих ответов не был понятен мне. В конце концов я нашел хорошее объяснение на 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>

Я нашел так много ответов со странными примерами здесь и в других открытых тикетах на stackoverflow или подобных форумах.

На мой взгляд, это самый простой вариант, как вы можете поместить переменную в качестве литеральной строки шаблона;

      const someString = "abc";
const regex = new RegExp(`^ someregex ${someString} someregex $`);

Как видите, я не ставлю косую черту в начале или в конце, конструктор RegExp реконструирует допустимый литерал регулярного выражения. Работает также с функцией yup match.

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

Эта самовызывающая функция будет перебирать 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'

Вы всегда можете использовать 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);
};

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

Простой метод:

      String.prototype.replaceAll = function(replaceThis, withThis) {
    const regexp = new RegExp(`${replaceThis}`, 'g');
    this.replace(regexp, withThis);
};

пример: регулярное выражение начинается с

      function startWith(char, value) {
    return new RegExp(`^[${char}]`, 'gi').test(value);
}

Как относительный новичок в JavaScript, принятый ответ /questions/29530905/kak-vyi-ispolzuete-peremennuyu-v-regulyarnom-vyirazhenii/29530921#29530921 отмечен / оценен, но он не очень интуитивно понятен.

Вот более простая интерпретация в качестве примера (с использованием простой IDE JavaScript ).

      myString = 'apple pie, banana loaf';

console.log(myString.replaceAll(/pie/gi, 'PIE'))
// apple PIE, banana loaf

console.log(myString.replaceAll(/\bpie\b/gi, 'PIE'))
// apple PIE, banana loaf

console.log(myString.replaceAll(/pi/gi, 'PIE'))
// apple PIEe, banana loaf

console.log(myString.replaceAll(/\bpi\b/gi, 'PIE'))
// [NO EFFECT] apple pie, banana loaf

const match_word = 'pie';

console.log(myString.replaceAll(/match_word/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf

console.log(myString.replaceAll(/\b`${bmatch_word}`\b/gi, '**PIE**'))
// [NO EFFECT] apple pie, banana loaf

// ----------------------------------------
// ... new RegExp(): be sure to \-escape your backslashes: \b >> \\b ...

const match_term = 'pie';
const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')

console.log(myString.replaceAll(match_re, 'PiE'))
// apple PiE, banana loaf

console.log(myString.replace(match_re, '**PIE**'))
// apple **PIE**, banana loaf

console.log(myString.replaceAll(match_re, '**PIE**'))
// apple **PIE**, banana loaf

Заявление

Например: замена (выделение цветом) слов в строке / предложении, [необязательно], если поисковый запрос соответствует более чем определенной пользователем пропорции совпадающего слова.

Примечание: сохраняется исходный регистр символов совпадающего термина. hl: выделять; re: регулярное выражение | регулярное выражение

      mySentence = "Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD', bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore."

function replacer(mySentence, hl_term, hl_re) {
    console.log('mySentence [raw]:', mySentence)
    console.log('hl_term:', hl_term, '| hl_term.length:', hl_term.length)
    cutoff = hl_term.length;
    console.log('cutoff:', cutoff)

    // `.match()` conveniently collects multiple matched items
    // (including partial matches) into an [array]
    const hl_terms  = mySentence.toLowerCase().match(hl_re, hl_term);
    if (hl_terms == null) {
        console.log('No matches to hl_term "' + hl_term + '"; echoing input string then exiting ...')
        return mySentence;
    }
    console.log('hl_terms:', hl_terms)
    for (let i = 0;  i < hl_terms.length; i++) {
        console.log('----------------------------------------')
        console.log('[' + i + ']:', hl_terms[i], '| length:', hl_terms[i].length, '| parseInt(0.7(length)):', parseInt(0.7*hl_terms[i].length))
        // TEST: if (hl_terms[i].length >= cutoff*10) {
        if (cutoff >= parseInt(0.7 * hl_terms[i].length)) {
            var match_term = hl_terms[i].toString();

            console.log('matched term:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))

            const match_re = new RegExp(`(\\b${match_term}\\b)`, 'gi')

            mySentence = mySentence.replaceAll(match_re, '<font style="background:#ffe74e">$1</font>');
        }
        else {
            var match_term = hl_terms[i].toString();
            console.log('NO match:', match_term, '[cutoff length:', cutoff, '| 0.7(matched term length):', parseInt(0.7 * hl_terms[i].length))
        }
    }
    return mySentence;
}

// TESTS:
// const hl_term = 'be';
// const hl_term = 'bee';
// const hl_term = 'before';
// const hl_term = 'book';
const hl_term = 'bookma';
// const hl_term = 'Leibniz';

// This regex matches from start of word:
const hl_re = new RegExp(`(\\b${hl_term}[A-z]*)\\b`, 'gi')

mySentence = replacer(mySentence, hl_term, hl_re);
console.log('mySentence [processed]:', mySentence)

Выход

      mySentence [raw]: Apple, boOk? BOoks; booKEd. BookMark, 'BookmarkeD',
bOOkmarks! bookmakinG, Banana; bE, BeEn, beFore.

hl_term: bookma | hl_term.length: 6
cutoff: 6
hl_terms: Array(4) [ "bookmark", "bookmarked", "bookmarks", "bookmaking" ]

----------------------------------------
[0]: bookmark | length: 8 | parseInt(0.7(length)): 5
matched term: bookmark [cutoff length: 6 | 0.7(matched term length): 5
----------------------------------------
[1]: bookmarked | length: 10 | parseInt(0.7(length)): 7
NO match: bookmarked [cutoff length: 6 | 0.7(matched term length): 7
----------------------------------------
[2]: bookmarks | length: 9 | parseInt(0.7(length)): 6
matched term: bookmarks [cutoff length: 6 | 0.7(matched term length): 6
----------------------------------------
[3]: bookmaking | length: 10 | parseInt(0.7(length)): 7
NO match: bookmaking [cutoff length: 6 | 0.7(matched term length): 7

mySentence [processed]: Apple, boOk? BOoks; booKEd.
<font style="background:#ffe74e">BookMark</font>, 'BookmarkeD',
<font style="background:#ffe74e">bOOkmarks</font>! bookmakinG,
Banana; bE, BeEn, beFore.

Не забывайте использовать new RegExp, поэтому вам нужно использовать строку как регулярное выражение.

Пример:

      const yourFunction = new RegExp(
        '^-?\\d+(?:\\.\\d{0,' + yourVar + '})?'
      )

На случай, если кто-то еще искал это, вот как вы сохраняете операторов:

      // BAD
let foo = "foo"
new RegExp(`${foo}\s`, "g");
// => /foos/g

// GOOD
let foo = "foo"
new RegExp(`${foo}${/\s/.source}`, "g");
// => /foo\s/g

Если вы передадите переменную с правильным синтаксисом, вы можете сделать это, используя приведенный ниже код.

Это дает дополнительное преимущество использования флагов в одной и той же переменной.

Также вам не нужно двойное побег \ в регулярном выражении, когда дело доходит до \w и Т. Д.

Я написал функцию для повторного использования:

      function replaceAll(str, from, to) {
    let re = new RegExp(`${from}`, "g");
    return str.replace(re, to);
}

let str = "my text from here";

let ans = replaceAll( str, "fromValue",  "toValue");
    ans = replaceAll( ans, "fromValue2", "toValue2");

console.log ( ans  );

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

      String.prototype.replaceAll = function(replaceThis, withThis) {
    const expr = `${replaceThis}`
    this.replace(new RegExp(expr, "g"), withThis);
};

Объяснение

The RegExpконструктор принимает 2 аргумента: выражение и флаги. Используя строку шаблона в выражении, мы можем передать переменную в класс, и он преобразует ее в/(value of the replaceThis variable)/g.

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

      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

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

Другие вопросы по тегам