Javascript Regex: Bagaimana cara menempatkan variabel di dalam ekspresi reguler?

206

Jadi misalnya:

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

Tapi ini tentu saja tidak berhasil :) Apakah ada cara untuk melakukan ini?

Adam
sumber
11
Ketahuilah bahwa jika Anda membiarkan pengguna memasok variabel ini, mudah bagi pengguna jahat untuk membuat crash aplikasi Anda melalui pengejaran bencana.
Tim Pietzcker
2
apa itu "ReGeX"? apakah itu nama variabel? itu membuat jawaban membingungkan dengan menyiratkan bahwa itu adalah bagian dari konstruksi RegExp (jika pembaca tidak melihat karakter aneh dalam pertanyaan).
Eduard

Jawaban:

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

Memperbarui

Per beberapa komentar, penting untuk dicatat bahwa Anda mungkin ingin keluar dari variabel jika ada potensi konten berbahaya (mis. Variabel tersebut berasal dari input pengguna)

Pembaruan ES6

Pada 2019, ini biasanya ditulis menggunakan string templat, dan kode di atas telah diperbarui. Jawaban aslinya adalah:

var regex = new RegExp("ReGeX" + testVar + "ReGeX");
...
string.replace(regex, "replacement");
Jason McCreary
sumber
5
Pastikan untuk melepaskan diri dari tali Anda! Lihat jawaban @zzzzBov
jtpereyda
Ini tidak berfungsi dalam kasus saya, dapatkah Anda melihat jsfiddle ini dan beri tahu saya jika apa yang harus saya lakukan jika saya ingin mengatur dinamika kode negara ke regexekspresi
Kirankumar Dafda
10
Satu hal penting yang perlu diingat adalah bahwa dalam string reguler karakter \ harus diloloskan sementara dalam regex literal (biasanya) karakter / perlu diloloskan. Jadi /\w+\//imenjadinew RegExp("\\w+/", "i")
Ali
3
Bagaimana dengan / g?
Qian Chen
Guys, saya perlu membagi regex ini /[^0-9.-[/g dengan dua bagian: / [^ 0-9 dan -] / g Bagaimana cara melakukannya?
Maks
79

Anda dapat menggunakan objek RegExp:

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

Maka Anda dapat membangun regexstringdengan cara apa pun yang Anda inginkan.

Anda dapat membaca lebih lanjut di sini .

steinar
sumber
var characterCount = parseInt (attrs.limitCharacterCount); console.log (characterCount); var specialCharactersValidation = RegExp baru ("/ ^ [a-zA-Z0-9] {" + characterCount + "} $ /"); / \ / ^ [a-zA-Z0-9] {7} $ \ // requestShipmentDirectives.js: 76 false main.js: 46 Uncaught TypeError: Tidak dapat membaca properti 'offsetWidth' of null Inilah yang terjadi ketika saya membuat RegEx Dynamic.
Ankit Tanna
31

Untuk membangun ekspresi reguler dari variabel dalam JavaScript, Anda harus menggunakan RegExpkonstruktor dengan parameter string.

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

tentu saja, ini adalah contoh yang sangat naif. Diasumsikan bahwa inputtelah keluar dengan benar untuk ekspresi reguler. Jika Anda berurusan dengan input pengguna, atau hanya ingin membuatnya lebih mudah untuk mencocokkan karakter khusus, Anda harus keluar dari karakter khusus :

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
sumber
Satu-satunya cara ini berhasil bagi saya adalah jika saya menghapus ReGeXteks. Jadi saya menggunakan:return new RegExp(input, flags);
Michael Rader
2
@MichaelRader, ya, teks "ReGeX" adalah bagian dari pertanyaan dan digunakan sebagai contoh, bukan sebagai sesuatu yang diperlukan untuk membuat kode berfungsi.
zzzzBov
1
lol baru menyadari bahwa itu hanya penampung Anda, tetapi sebagai noob ini butuh waktu bagi saya untuk mencari tahu. Terima kasih.
Michael Rader
Saya mengerti mengapa string harus diloloskan. Tapi mengapa '\\ $ &' ​​digunakan sebagai pengganti
Sherin Binu
2
\\mewakili satu \karakter, $&adalah substring yang cocok .
zzzzBov
7

jika Anda menggunakan literal template es6 adalah sebuah opsi ...

string.replace(new RegExp(`ReGeX${testVar}ReGeX`), "replacement")
shunryu111
sumber
itu tidak bekerja dengan templat literal. Saya menggunakan regexp untuk memvalidasi kata sandi di aplikasi saya, dan saya ingin parametrize panjang maks dan min dalam string ekspresi reguler saya dan itu tidak berfungsi. `` `const newRegExp = new RegExp ( ^[^\s]{${4},${32}}$); export const validatePassword = value => value.match (newRegExp); `` `
p7adams
6

Anda selalu dapat memberikan ekspresi reguler sebagai string, yaitu "ReGeX" + testVar + "ReGeX". Anda mungkin harus melarikan diri beberapa karakter di dalam string Anda (misalnya, kutipan ganda), tetapi untuk sebagian besar kasus itu setara.

Anda juga dapat menggunakan RegExpkonstruktor untuk meneruskan flag ( lihat dokumen ).

Nikita Rybak
sumber
3

Anda dapat membuat ekspresi reguler di JS dalam salah satu dari dua cara:

  1. Menggunakan literal ekspresi reguler - /ab{2}/g
  2. Menggunakan konstruktor ekspresi reguler - new RegExp("ab{2}", "g").

Literal ekspresi reguler adalah konstan, dan tidak dapat digunakan dengan variabel. Ini dapat dicapai dengan menggunakan konstruktor. Struktur konstruktor RegEx adalah

new RegExp(regularExpressionString, modifiersString)

Anda dapat menanamkan variabel sebagai bagian dari regularExpressionString. Sebagai contoh,

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

Ini akan cocok dengan penampilan pola apa pun cdcdcd.

Ben Carp
sumber
2

Berikut adalah fungsi yang tidak berguna yang mengembalikan nilai yang dibungkus oleh karakter tertentu. :)

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)
Jakob Sternberg
sumber
2

jawaban yang diterima tidak bekerja untuk saya dan tidak mengikuti contoh MDN

lihat bagian 'Keterangan' di tautan di atas

Saya akan pergi dengan yang berikut ini bekerja untuk saya:

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

// that makes dynamicRegExp = /findMe/gi
Timothy Mitchell
sumber
1
Itu masih berfungsi. Masalahnya adalah bahwa 'ReGeX' + testVar + 'ReGeX' membuat solusi membingungkan. Menambahkan contoh yang sebenarnya akan jelas menurut saya. var testVar = '321'; var regex = RegExp baru ("[" + testVar + "] {2}", "g"); // di atas setara dengan / [321] {2} / g
HelloWorldPeace
1

Ini hanya perlu menyiapkan variabel string terlebih dahulu dan kemudian mengonversinya ke RegEx.

sebagai contoh:

Anda ingin menambahkan minLengthdan MaxLengthdengan variabel ke 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
}

sekarang jika Anda mengubah nilai MaxLengthatau MinLength, Ini akan berubah di semua RegExs.

Semoga bermanfaat. Maaf tentang bahasa Inggris saya.

Abbas Habibnejad
sumber