JavaScript Regex: Jak wstawić zmienną do wyrażenia regularnego?


206

Na przykład:

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

Ale to oczywiście nie działa :) Czy jest na to sposób?


11
Pamiętaj, że jeśli pozwolisz użytkownikowi podać tę zmienną, złośliwemu użytkownikowi łatwo jest zawiesić aplikację poprzez katastrofalne cofnięcie.
— Tim Pietzcker

2
co to jest „ReGeX”? czy to jest nazwa zmiennej? sprawia, że ​​odpowiedzi są mylące, sugerując, że jest to część konstrukcji RegExp (na wypadek, gdyby czytelnik nie widział tych dziwnych znaków w pytaniu).
— Eduard,

Odpowiedzi:


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

Aktualizacja

W przypadku niektórych komentarzy należy zauważyć, że możesz chcieć uciec od zmiennej, jeśli istnieje możliwość wystąpienia złośliwej zawartości (np. Zmienna pochodzi z danych wprowadzonych przez użytkownika)

Aktualizacja ES6

W 2019 r. Byłoby to zwykle napisane przy użyciu ciągu szablonu, a powyższy kod został zaktualizowany. Oryginalna odpowiedź brzmiała:

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

5
Upewnij się, aby uciec od łańcucha! Zobacz odpowiedź @zzzzBov
— jtpereyda

To nie działa w moim przypadku, czy mógłbyś rzucić okiem na ten jsfiddle i dać mi znać, co muszę zrobić, jeśli chcę ustawić dynamikę kodu kraju w regexwyrażeniu
— Kirankumar Dafda

10
Jedną ważną rzeczą do zapamiętania jest to, że w regularnych ciągach znak \ musi być poprzedzony znakiem ucieczki, podczas gdy w dosłownym wyrażeniu regularnym (zwykle) znak / musi być poprzedzony znakiem ucieczki. Tak się /\w+\//istajenew RegExp("\\w+/", "i")
— Ali

3
Co powiesz na / g?
— Qian Chen,

Chłopaki, muszę podzielić to wyrażenie regularne /[^0-9.-]/g na dwie części: / [^ 0-9 i -] / g Jak to zrobić?
— maks.

79

Możesz użyć obiektu RegExp:

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

Następnie możesz budować regexstringw dowolny sposób.

Możesz przeczytać więcej na ten temat tutaj .


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: Nie można odczytać właściwości „offsetWidth” o wartości null To właśnie dzieje się, gdy robię RegEx Dynamic.
— Ankit Tanna

31

Aby zbudować wyrażenie regularne ze zmiennej w JavaScript, musisz użyć RegExpkonstruktora z parametrem string.

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

oczywiście jest to bardzo naiwny przykład. Zakłada się, że inputpoprawnie zapisano go dla wyrażenia regularnego. Jeśli masz do czynienia z wprowadzaniem danych przez użytkownika lub po prostu chcesz wygodniej dopasowywać znaki specjalne, musisz uciec od znaków specjalnych :

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);
}

Jedynym sposobem, w jaki mi to działało, było usunięcie ReGeXtekstu. Użyłem więc:return new RegExp(input, flags);
— Michael Rader,

2
@MichaelRader, tak, tekst „ReGeX” był częścią pytania i został użyty jako przykład, a nie jako coś, co jest wymagane, aby kod działał.
— zzzzBov

1
Lol właśnie zdał sobie sprawę, że to tylko twój symbol zastępczy, ale jako noob zajęło mi to trochę czasu, żeby to rozgryźć. Dzięki.
— Michael Rader

Rozumiem, dlaczego ciąg musi być usuwany. Ale dlaczego „\\ $ &” jest używane jako zamiennik
— Sherin Binu

2
\\reprezentuje pojedynczy \znak, $&jest dopasowanym podciągiem .
— zzzzBov

7

jeśli używasz literałów szablonu es6 są opcją ...

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

nie działa z literałami szablonów. Używam wyrażenia regularnego do sprawdzania poprawności hasła w mojej aplikacji i chciałem sparametryzować maksymalną i minimalną długość w moim ciągu wyrażeń regularnych i to nie działa. `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = wartość => wartość.match (newRegExp); ``
— p7adams

6

Zawsze możesz podać wyrażenie regularne jako ciąg znaków, tj "ReGeX" + testVar + "ReGeX". Być może będziesz musiał uciec przed niektórymi znakami w ciągu (np. Podwójny cudzysłów), ale w większości przypadków jest to równoważne.

Możesz także użyć RegExpkonstruktora, aby przekazać flagi ( zobacz dokumentację ).


3

Możesz utworzyć wyrażenia regularne w JS na jeden z dwóch sposobów:

  1. Używanie literału wyrażenia regularnego - /ab{2}/g
  2. Korzystanie z konstruktora wyrażeń regularnych - new RegExp("ab{2}", "g").

Literały wyrażeń regularnych są stałe i nie można ich używać ze zmiennymi. Można to osiągnąć za pomocą konstruktora. Struktura konstruktora RegEx jest

new RegExp(regularExpressionString, modifiersString)

Zmienne można osadzać jako część regularExpressionString. Na przykład,

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

Będzie pasować do każdego wyglądu wzoru cdcdcd.


2

Oto całkiem bezużyteczna funkcja, która zwraca wartości zawinięte przez określone znaki. :)

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

zaakceptowana odpowiedź nie działa dla mnie i nie jest zgodna z przykładami MDN

patrz sekcja „Opis” w powyższym linku

Wybrałbym następujące, które działają dla mnie:

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

// that makes dynamicRegExp = /findMe/gi

1
Wciąż działa. Problem polega na tym, że „ReGeX” + testVar + „ReGeX” sprawia, że ​​rozwiązanie jest mylące. Dodanie faktycznego przykładu wyjaśniłoby, moim zdaniem, pewne rzeczy. var testVar = „321”; var regex = new RegExp („[” + testVar + ”] {2}”, „g”); // powyżej odpowiednika / [321] {2} / g
— HelloWorldPeace

1

Trzeba tylko najpierw przygotować zmienną łańcuchową, a następnie przekonwertować ją na RegEx.

na przykład:

Chcesz dodać minLengthi MaxLengthza pomocą zmiennej do 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
}

teraz, jeśli zmienisz wartość MaxLengthlub MinLength, to zmieni się we wszystkich RegExs.

Mam nadzieję, że się przydadzę. Przepraszam również za mój angielski.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.