Javascript Regex: Як помістити змінну всередині регулярного виразу?


206

Так, наприклад:

function(input){
    var testVar = input;
    string = ...
    string.replace(/ReGeX + testVar + ReGeX/, "replacement")
}

Але це, звичайно, не працює :) Чи є спосіб це зробити?


11
Майте на увазі, що якщо ви дозволите користувачеві надати цю змінну, зловмисник може легко зламати вашу програму за допомогою катастрофічного зворотного відстеження.
Тім Піцкер

2
що таке "ReGeX"? це ім'я змінної? він робить заплутані відповіді, маючи на увазі, що це частина побудови RegExp (у випадку, якщо читач не побачив цих дивних символів у питанні).
Едуард

Відповіді:


272
const regex = new RegExp(`ReGeX${testVar}ReGeX`);
...
string.replace(regex, "replacement");

Оновлення

У деяких коментарях важливо зауважити, що ви можете вийти з змінної, якщо є потенціал для шкідливого вмісту (наприклад, змінна надходить від введення користувача)

Оновлення ES6

У 2019 році це зазвичай пишеться за допомогою рядка шаблону, і вищевказаний код було оновлено. Оригінальна відповідь:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");

5
Переконайтесь, що уникнути своєї строки! Дивіться відповідь @zzzzBov
jtpereyda

У моєму випадку це не працює, чи можете ви, будь ласка, ознайомтеся з цією jsfiddle і дозвольте мені знати, що мені робити, якщо я хочу встановити динамічний код країни на regexвираз
Kirankumar Dafda

10
Важливо пам’ятати, що у звичайних рядках потрібно уникати символу \ у той час, коли в прямому виразі (зазвичай) символ / слід уникати. Так /\w+\//iстаєnew RegExp("\\w+/", "i")
Алі

3
Як щодо / г?
Qian Chen

Хлопці, мені потрібно розділити цей регекс / зроблений^0-9.- снимки/g на дві частини: / [^ 0-9 та -] / g Як це зробити?
макс

79

Ви можете використовувати об’єкт RegExp:

var regexstring = "whatever";
var regexp = new RegExp(regexstring, "gi");
var str = "whateverTest";
var str2 = str.replace(regexp, "other");
document.write(str2);

Тоді ви можете побудувати regexstringбудь-яким способом.

Більше про це можна прочитати тут .


var characterCount = parseInt (attrs.limitCharacterCount); console.log (characterCount); var specialCharactersValidation = новий RegExp ("/ ^ [a-zA-Z0-9] {" + characterCount + "} $ /"); / \ / ^ [a-zA-Z0-9] {7} $ \ // requestShipmentDirectives.js: 76 false main.js: 46 Uncaught TypeError: Неможливо прочитати властивість 'offsetWidth' null Це те, що відбувається, коли я роблю RegEx Dynamic.
Анкіт Танна

31

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

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

звичайно, це дуже наївний приклад. Це передбачає, що inputце було правильно уникнуто для регулярного вираження. Якщо ви маєте справу з введенням користувача або просто хочете зробити зручніше відповідати спеціальним символам, вам потрібно буде уникати спеціальних символів :

function regexEscape(str) {
    return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
}

function reg(input) {
    var flags;
    //could be any combination of 'g', 'i', and 'm'
    flags = 'g';
    input = regexEscape(input);
    return new RegExp('ReGeX' + input + 'ReGeX', flags);
}

Єдиний спосіб для мене це було, якщо я видалив ReGeXтекст. Тому я використав:return new RegExp(input, flags);
Michael Rader

2
@MichaelRader, так, текст "ReGeX" був частиною запитання і використовувався як приклад, а не як щось, що потрібно для роботи коду.
zzzzBov

1
LOL щойно зрозумів, що це лише твій заповнювач, але як noob це знадобило мені деякий час, щоб зрозуміти. Дякую.
Майкл Радер

Я розумію, чому рядок потрібно уникати. Але чому "\\ $ &" використовується як заміна
Шерін Біну,

2
\\являє собою єдиний \символ, $&- це відповідна підрядка .
zzzzBov

7

якщо ви використовуєте літеральні шаблони es6 - це варіант ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")

він не працює з літералами шаблонів. Я використовую regexp для перевірки пароля в моєму додатку, і я хотів параметризувати максимальну та мінімальну довжини в моєму рядку регулярних виразів, і це не працює. `` `const newRegExp = новий RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = value => value.match (newRegExp); `` `
p7adams

6

Ви завжди можете надати регулярний вираз у вигляді рядка, тобто "ReGeX" + testVar + "ReGeX" . Можливо, вам доведеться уникати деяких символів всередині рядка (наприклад, подвійна цитата), але в більшості випадків це еквівалентно.

Ви також можете використовувати RegExpконструктор для передачі прапорів ( див. Документи ).


3

Ви можете створювати регулярні вирази в JS одним із двох способів:

  1. Використання буквеного регулярного вираження - /ab{2}/g
  2. Використання конструктора регулярних виразів - new RegExp("ab{2}", "g").

Літерали регулярного виразу постійні, і їх не можна використовувати зі змінними. Цього можна досягти за допомогою конструктора. Стратегія конструктора RegEx є

new RegExp(regularExpressionString, modifiersString)

Ви можете вбудовувати змінні як частину regularExpressionString. Наприклад,

var pattern="cd"
var repeats=3
new RegExp(`${pattern}{${repeats}}`, "g") 

Це буде відповідати будь-якій зовнішності візерунка cdcdcd.


2

Ось досить непотрібна функція, яка повертає значення, обгорнуті певними символами. :)

jsfiddle: https://jsfiddle.net/squadjot/43agwo6x/

function getValsWrappedIn(str,c1,c2){
    var rg = new RegExp("(?<=\\"+c1+")(.*?)(?=\\"+c2+")","g"); 
    return str.match(rg);
    }

var exampleStr = "Something (5) or some time (19) or maybe a (thingy)";
var results =  getValsWrappedIn(exampleStr,"(",")")

// Will return array ["5","19","thingy"]
console.log(results)

2

прийнята відповідь не працює для мене і не відповідає прикладами MDN

дивіться розділ "Опис" у посиланні вище

Я б пішов із наступним, що це працює для мене:

let stringThatIsGoingToChange = 'findMe';
let flagsYouWant = 'gi' //simple string with flags
let dynamicRegExp = new RegExp(`${stringThatIsGoingToChange}`, flagsYouWant)

// that makes dynamicRegExp = /findMe/gi

1
Це все ще працює. Проблема полягає в тому, що 'ReGeX' + testVar + 'ReGeX' робить рішення заплутаним. Додавання фактичного прикладу могло б зрозуміти речі, на мою думку. var testVar = '321'; var regex = new RegExp ("[" + testVar + "] {2}", "g"); // вище еквівалент / [321] {2} / g
HelloWorldPeace

1

Потрібно лише спершу підготувати струнну змінну, а потім перетворити її в RegEx.

наприклад:

Ви хочете додати minLengthі MaxLengthзі змінною до RegEx:

function getRegEx() {
    const minLength = "5"; // for exapmle: min is 5
    const maxLength = "12"; // for exapmle: man is 12

    var regEx = "^.{" + minLength + ","+ maxLength +"}$"; // first we make a String variable of our RegEx
    regEx = new RegExp(regEx, "g"); // now we convert it to RegEx

    return regEx; // In the end, we return the RegEx
}

тепер, якщо ви зміните значення MaxLengthабоMinLength , воно зміниться у всіх RegEx.

Сподіваюся, що буде корисно. Також шкода моєї англійської.

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