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
Как насчет / г?
Цянь Чен
Ребята, мне нужно разделить это регулярное выражение /[^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 = new 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);
}
zzzzBov
источник
Единственный способ, которым это работало для меня, был, если я удалил ReGeXтекст. Поэтому я использовал:return new RegExp(input, flags);
Майкл Рэйдер
2
@MichaelRader, да, текст «ReGeX» был частью вопроса и использовался в качестве примера, а не как то, что требуется для работы кода.
zzzzBov
1
LOL только что понял, что это был только ваш заполнитель, но, как нуб, мне потребовалось некоторое время, чтобы выяснить. Спасибо.
Майкл Рэйдер
Я понимаю, почему строка должна быть экранирована. Но почему «\\ $ &» используется в качестве замены
Шерин Бину
2
\\представляет один \символ, $&является соответствующей подстрокой .
zzzzBov
7

если вы используете литералы шаблона es6 вариант ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
shunryu111
источник
это не работает с литералами шаблона. Я использую регулярное выражение для проверки пароля в моем приложении, и я хотел параметризовать максимальную и минимальную длину в моей строке регулярного выражения, и это не работает. `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); экспорт const validatePassword = значение => значение.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)

Вы можете встраивать переменные как часть normalExpressionString. Например,

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, оно изменится во всех регулярных выражениях.

Надеюсь быть полезным. Также извините за мой английский.

Аббас Хабибнеджад
источник