Як ви використовуєте змінну в регулярному виразі?


1377

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

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

Але я хочу зробити щось подібне:

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

Але очевидно, це замінить лише текст "replaceThis"... тож як я можу передати цю змінну в мою рядок regex?


9
Зауважте, що зараз ми працюємо над додаванням цієї функціональності в JavaScript, якщо у вас є думка про неї, будь ласка, приєднуйтесь до дискусії.
Бенджамін Груенбаум

Відповіді:


1839

Замість використання /regex/gсинтаксису ви можете побудувати новий об'єкт RegExp :

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

Ви можете динамічно створювати об'єкти регулярного вираження таким чином. Тоді ви зробите:

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

272
Якщо вам потрібно використовувати такий вислів , як /\/word\:\w*$/, переконайтеся , щоб уникнути ваші зворотні Слеш: new RegExp( '\\/word\\:\\w*$' ).
Джонатан Свінні

2
@gravityboy Ви можете зробити ('' + myNumber) .replace (/ 10 / g, 'a') або якщо вам потрібні шістнадцяткові числа, ви можете виконати parseInt ('' + myNumber, 16) для перетворення в шістнадцятковий з десяткової.
Ерік Венделін

29
Питання передбачає, що RegEx використовується лише для постійної заміни рядків. Таким чином, ця відповідь є неправильною, оскільки вона не зможе, якщо рядок містить мета символи RegEx Сумно за те, що його голосують так високо, завдасть багато головних болів ...
дрон

16
Приклад передачі змінної зробив би це хорошою відповіддю. Я все ще борюся, прочитавши це.
Гусак

3
@JonathanSwinney: /не має особливого значення, якщо ви будуєте регулярний вираз з рядка, тому вам не потрібно уникати цього. /\/word\:\w*$/має бутиnew RegExp('/word\\:\\w*$')
Давид Хорват

211

Як згадував Ерік Венделін, ви можете зробити щось подібне:

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


4
Ви знаєте, що перший параметр, який потрібно замінити, може бути звичайним рядком і не повинен бути регулярним виразом? str1 = "."; alert ("узгодження шаблону.". заміна (str1, "string"));
десь

@some: звичайно. Це тому, що наведений вище приклад є тривіальним. Коли вам потрібно шукати або замінювати шаблон, поєднаний із звичайною рядком, наприклад, виконайте str.match (новий RegExp ("https? //" + RegExp.escape (myDomainName)). Це дратує те, що функція втечі не вбудовано.
Gracenotes

(продовження) Плюс, очевидний JC Grubbs вимагав глобальної заміни; реалізація глобальної заміни String.replace (String, String) може бути повільною для великого введення. Я просто кажу, що два найкращі рішення є помилковими, і вони не зможуть несподівано отримати певний вклад.
Граценоти

4
developer.mozilla.org/en-US/docs/JavaScript/Guide/… пропонує подібну функцію, але вони виключають -та включають =!:/.
chbrown

8
Правильний термін - "втеча", а не "цитата". Просто BTW.
Лоуренс Дол

118

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

Як завжди: не використовуйте регулярні вирази, якщо не потрібно. Для простої заміни рядка ідіома:

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

Тоді вам не доведеться турбуватися про питання цитування, згадані у відповіді Грейнотеса.


11
А ви виміряли, що це швидше, ніж регулярний вираз?
Мітар

3
Це здається кращим, особливо коли потрібно відповідати спеціальним символам регулярного вираження типу "."
Креаз

1
Гм ... Не розділяється, також беруть RegExp; якщо це так, чи не викликало б це та ж проблему? У будь-якому випадку ... .split (). Join () може бути повільнішим на деяких платформах, оскільки це дві операції, тоді як .replace () - одна операція і може бути оптимізована.

5
@ PacMan--: і те, splitі replaceможе приймати або рядок, або RegExpоб'єкт. Проблема, replaceяка splitне полягає в тому, що при використанні рядка ви отримуєте лише одну заміну.
bobince


38

Якщо ви хочете отримати ВСІ події ( 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.

Дякую тобі! (афакт, ваша єдина відповідь явно з rxінтерполяцією Emacs / -style, через рядки шаблону.)
sam boosalis

34

Для всіх, хто хоче використовувати змінну з методом відповідності , це працювало для мене

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight


20
this.replace( new RegExp( replaceThis, 'g' ), withThis );

Мені подобається ця відповідь, оскільки вона не створює зайву (& безглузду) змінну.
Вік

14

Ви хочете динамічно будувати регулярний вираз, і для цього правильним рішенням є використання 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]"

9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Тест за допомогою цього інструменту


5
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

Ось ще одна замінаВсі реалізація:

    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

І версія 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!"

чому потік? coffeescript -IS- javascript з власним специфічним синтаксисом.
захопливий

robot.name=hubotне JavaScript.
codepleb

3

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


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


2

Ви можете використовувати це, якщо 1 долар не працює з вами

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

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

Ваше рішення тут:

Передайте змінну в регулярний вираз.

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

Тож тепер Ви можете передати змінну у функції заміни.


Ваша змінна sit_with буде містити елемент DOM, а не саме значення
Ben Taliadoros

1

Ця функція самостійного виклику повторюватиме заміщення замінювальних елементів за допомогою індексу та змінює замість заміни заміни [індекс] глобально на рядку з кожним проходом.

  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'

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


1
Ви перезаписуєте змінну закриття, тут не потрібно використовувати var. Крім того , якщо ви передаєте \bабо \1він зламається.
CyberAP

0

Для багаторазової заміни без регулярних виразів я пішов із наступним:

      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

Тут була знайдена важлива частина рішення

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