Ekspresi reguler untuk mendapatkan string antara dua string dalam JavaScript
Solusi paling lengkap yang akan bekerja di sebagian besar kasus adalah menggunakan grup penangkap dengan pola pencocokan titik malas . Namun, sebuah titik .
dalam regex JavaScript tidak cocok dengan karakter pemisah baris, jadi, apa yang akan berfungsi dalam 100% kasus adalah konstruksi [^]
atau [\s\S]
/ [\d\D]
/ [\w\W]
.
ECMAScript 2018 dan solusi kompatibel yang lebih baru
Dalam lingkungan JavaScript yang mendukung ECMAScript 2018 , s
pengubah memungkinkan .
untuk mencocokkan karakter apa pun termasuk karakter line break, dan mesin regex mendukung tampilan di balik panjang variabel. Jadi, Anda bisa menggunakan regex like
var result = s.match(/(?<=cow\s+).*?(?=\s+milk)/gs); // Returns multiple matches if any
// Or
var result = s.match(/(?<=cow\s*).*?(?=\s*milk)/gs); // Same but whitespaces are optional
Dalam kedua kasus, posisi saat ini diperiksa cow
dengan spasi putih 1/0 atau lebih setelahnya cow
, maka 0+ karakter sesedikit mungkin dicocokkan dan dikonsumsi (= ditambahkan ke nilai pertandingan), dan kemudian milk
diperiksa untuk (dengan 1/0 atau lebih spasi putih sebelum substring ini).
Skenario 1: Input satu baris
Ini dan semua skenario lainnya di bawah ini didukung oleh semua lingkungan JavaScript. Lihat contoh penggunaan di bagian bawah jawaban.
cow (.*?) milk
cow
ditemukan pertama, lalu spasi, lalu 0+ karakter apa pun selain karakter baris, sesedikit mungkin *?
kuantifier malas, dimasukkan ke Grup 1 dan kemudian spasi dengan milk
harus mengikuti (dan yang dicocokkan dan dikonsumsi , juga ).
Skenario 2: Input multiline
cow ([\s\S]*?) milk
Di sini, cow
dan spasi dicocokkan terlebih dahulu, maka 0+ karakter apa pun yang sesedikit mungkin dicocokkan dan ditangkap ke dalam Grup 1, dan kemudian spasi dengan milk
dicocokkan.
Skenario 3: Pertandingan yang tumpang tindih
Jika Anda memiliki string seperti >>>15 text>>>67 text2>>>
dan Anda perlu mendapatkan 2 kecocokan di antara >>>
+ number
+ whitespace
dan >>>
, Anda tidak dapat menggunakan />>>\d+\s(.*?)>>>/g
karena ini hanya akan menemukan 1 kecocokan karena fakta >>>
sebelumnya 67
sudah dikonsumsi saat menemukan kecocokan pertama. Anda dapat menggunakan lookahead positif untuk memeriksa keberadaan teks tanpa benar-benar "melahapnya" (yaitu menambahkan kecocokan):
/>>>\d+\s(.*?)(?=>>>)/g
Lihat menghasilkan demo regex onlinetext1
dan text2
sebagai konten Grup 1 ditemukan.
Lihat juga Cara mendapatkan semua kecocokan yang mungkin tumpang tindih untuk sebuah string .
Pertimbangan kinerja
Pola pencocokan titik malas ( .*?
) di dalam pola regex dapat memperlambat eksekusi skrip jika input yang sangat panjang diberikan. Dalam banyak kasus, teknik membuka gulungan-the-loop membantu untuk tingkat yang lebih besar. Mencoba mengambil semua antara cow
dan milk
dari "Their\ncow\ngives\nmore\nmilk"
, kita melihat bahwa kita hanya perlu mencocokkan semua baris yang tidak dimulai dengan milk
, jadi, alih-alih cow\n([\s\S]*?)\nmilk
kita dapat menggunakan:
/cow\n(.*(?:\n(?!milk$).*)*)\nmilk/gm
Lihat demo regex (jika ada \r\n
, gunakan /cow\r?\n(.*(?:\r?\n(?!milk$).*)*)\r?\nmilk/gm
). Dengan string uji kecil ini, peningkatan kinerja dapat diabaikan, tetapi dengan teks yang sangat besar, Anda akan merasakan perbedaannya (terutama jika garisnya panjang dan garis putus tidak terlalu banyak).
Contoh penggunaan regex dalam JavaScript:
//Single/First match expected: use no global modifier and access match[1]
console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]);
// Multiple matches: get multiple matches with a global modifier and
// trim the results if length of leading/trailing delimiters is known
var s = "My cow always gives milk, thier cow also gives milk";
console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);}));
//or use RegExp#exec inside a loop to collect all the Group 1 contents
var result = [], m, rx = /cow (.*?) milk/g;
while ((m=rx.exec(s)) !== null) {
result.push(m[1]);
}
console.log(result);
Menggunakan String#matchAll
metode modern
const s = "My cow always gives milk, thier cow also gives milk";
const matches = s.matchAll(/cow (.*?) milk/g);
console.log(Array.from(matches, x => x[1]));