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 , spengubah 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 cowdengan spasi putih 1/0 atau lebih setelahnya cow, maka 0+ karakter sesedikit mungkin dicocokkan dan dikonsumsi (= ditambahkan ke nilai pertandingan), dan kemudian milkdiperiksa 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
cowditemukan pertama, lalu spasi, lalu 0+ karakter apa pun selain karakter baris, sesedikit mungkin *?kuantifier malas, dimasukkan ke Grup 1 dan kemudian spasi dengan milkharus mengikuti (dan yang dicocokkan dan dikonsumsi , juga ).
Skenario 2: Input multiline
cow ([\s\S]*?) milk
Di sini, cowdan spasi dicocokkan terlebih dahulu, maka 0+ karakter apa pun yang sesedikit mungkin dicocokkan dan ditangkap ke dalam Grup 1, dan kemudian spasi dengan milkdicocokkan.
Skenario 3: Pertandingan yang tumpang tindih
Jika Anda memiliki string seperti >>>15 text>>>67 text2>>>dan Anda perlu mendapatkan 2 kecocokan di antara >>>+ number+ whitespacedan >>>, Anda tidak dapat menggunakan />>>\d+\s(.*?)>>>/gkarena ini hanya akan menemukan 1 kecocokan karena fakta >>>sebelumnya 67sudah 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 text2sebagai 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 cowdan milkdari "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]*?)\nmilkkita 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#matchAllmetode 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]));