Anda dapat mengakses menangkap grup seperti ini:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
console.log(match[1]); // abc
Dan jika ada beberapa pertandingan, Anda dapat mengulanginya:
var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
console.log(match[0])
match = myRegexp.exec(myString);
}
Edit: 2019-09-10
Seperti yang Anda lihat cara untuk mengulang beberapa pertandingan tidak terlalu intuitif. Ini mengarah pada usulan String.prototype.matchAll
metode. Metode baru ini diharapkan dikirimkan dalam spesifikasi ECMAScript 2020 . Ini memberi kami API bersih dan menyelesaikan beberapa masalah. Sudah mulai mendarat di browser utama dan mesin JS sebagai Chrome 73+ / Node 12+ dan Firefox 67+.
Metode mengembalikan iterator dan digunakan sebagai berikut:
const string = "something format_abc";
const regexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
const matches = string.matchAll(regexp);
for (const match of matches) {
console.log(match);
console.log(match.index)
}
Karena mengembalikan iterator, kita dapat mengatakan itu malas, ini berguna ketika menangani kelompok penangkapan yang sangat banyak, atau string yang sangat besar. Tetapi jika Anda perlu, hasilnya dapat dengan mudah diubah menjadi Array dengan menggunakan sintaks spread atau Array.from
metode:
function getFirstGroup(regexp, str) {
const array = [...str.matchAll(regexp)];
return array.map(m => m[1]);
}
// or:
function getFirstGroup(regexp, str) {
return Array.from(str.matchAll(regexp), m => m[1]);
}
Sementara itu, sementara proposal ini mendapat dukungan yang lebih luas, Anda dapat menggunakan paket shim resmi .
Juga, cara kerja internal metode ini sederhana. Implementasi yang setara menggunakan fungsi generator adalah sebagai berikut:
function* matchAll(str, regexp) {
const flags = regexp.global ? regexp.flags : regexp.flags + "g";
const re = new RegExp(regexp, flags);
let match;
while (match = re.exec(str)) {
yield match;
}
}
Salinan regexp asli dibuat; ini untuk menghindari efek samping karena mutasi lastIndex
properti ketika melewati pertandingan multple.
Juga, kita perlu memastikan regexp memiliki flag global untuk menghindari infinite loop.
Saya juga senang melihat bahwa bahkan pertanyaan StackOverflow ini dirujuk dalam diskusi proposal .
var match = myString.match(myRegexp); // alert(match[1])
?string = string.substring(match.index + match[0].length)
Berikut adalah metode yang dapat Anda gunakan untuk mendapatkan grup penangkap ke- n untuk setiap pertandingan:
sumber
Ini
\b
bukan hal yang persis sama. (Berhasil--format_foo/
, tetapi tidak berhasilformat_a_b
) Tapi saya ingin menunjukkan alternatif untuk ekspresi Anda, yang tidak masalah Tentu saja,match
panggilan itu yang penting.sumber
format_a_b
" sebagai pemikiran setelah 6 tahun yang lalu, dan saya tidak ingat apa yang saya maksud di sana ... :-) Saya kira itu berarti "tidak bekerja untuk menangkapa
hanya", yaitu. bagian alfabet pertama setelahformat_
.Sehubungan dengan contoh tanda kurung multi-pertandingan di atas, saya mencari jawaban di sini setelah tidak mendapatkan apa yang saya inginkan dari:
Setelah melihat panggilan fungsi yang agak berbelit-belit dengan while dan .push () di atas, saya sadar bahwa masalahnya dapat diselesaikan dengan sangat elegan dengan mystring.replace () sebagai gantinya (penggantian BUKAN intinya, dan bahkan tidak dilakukan , opsi panggilan fungsi rekursif BERSIH, built-in untuk parameter kedua adalah!):
Setelah ini, saya tidak berpikir saya akan menggunakan .match () untuk hampir tidak ada lagi.
sumber
Terakhir, saya menemukan satu baris kode yang berfungsi baik untuk saya (JS ES6):
Ini akan mengembalikan:
sumber
replace
oleh Alexz karena yang satu ini kurang melihat ke depan-y dan lebih elegan untuk beberapa hasil. Kerja bagus untuk ini, Sebastien H.Terminologi yang digunakan dalam jawaban ini:
someString.match(regexPattern)
./format_(.*?)/g
mana(.*?)
akan menjadi kelompok yang cocok.) Ini berada dalam pola yang cocok .Deskripsi
Untuk mendapatkan akses ke grup yang cocok , di masing-masing pola yang cocok , Anda memerlukan fungsi atau sesuatu yang mirip dengan iterate selama pertandingan . Ada beberapa cara Anda bisa melakukan ini, seperti yang ditunjukkan oleh banyak jawaban lainnya. Sebagian besar jawaban lain menggunakan perulangan sementara untuk mengulangi semua pola yang cocok , tapi saya pikir kita semua tahu potensi bahaya dengan pendekatan itu. Penting untuk mencocokkan dengan
new RegExp()
bukan hanya pola itu sendiri, yang hanya disebutkan dalam komentar. Ini karena.exec()
metode ini berperilaku mirip dengan fungsi generator - berhenti setiap kali ada kecocokan , tetapi tetap.lastIndex
melanjutkan dari.exec()
panggilan berikutnya .Contoh kode
Di bawah ini adalah contoh dari fungsi
searchString
yang mengembalikan suatuArray
dari semua pola yang cocok , di mana masingmatch
- masing adalahArray
dengan semua kelompok yang cocok yang berisi . Alih-alih menggunakan loop sementara, saya telah memberikan contoh menggunakan keduaArray.prototype.map()
fungsi serta cara yang lebih performant - menggunakanfor
-loop polos .Versi ringkas (lebih sedikit kode, lebih banyak gula sintaksis)
Ini kurang berkinerja karena mereka pada dasarnya menerapkan
forEach
-loop daripada yang lebih cepatfor
-loop.Versi performan (lebih banyak kode, lebih sedikit gula sintaksis)
Saya belum membandingkan alternatif ini dengan yang sebelumnya disebutkan dalam jawaban lain, tetapi saya ragu pendekatan ini kurang berkinerja dan kurang aman-gagal daripada yang lain.
sumber
String#matchAll
(lihat Tahap 3 Draft / 7 Desember 2018 usulan ), menyederhanakan acccess untuk semua kelompok dalam objek pertandingan (diingat bahwa Kelompok 0 adalah seluruh pertandingan, sementara kelompok lanjut sesuai dengan kelompok menangkap dalam pola):Metode ini menghasilkan output yang mirip dengan
Regex.Matches
di C #,re.finditer
dengan Python,preg_match_all
dalam PHP.Lihat demo JS (diuji di Google Chrome 73.0.3683.67 (versi resmi), beta (64-bit)):
The
console.log([...matches])
showAnda juga bisa mendapatkan nilai kecocokan atau nilai grup tertentu menggunakan
CATATAN : Lihat detail kompatibilitas browser .
sumber
Sintaks Anda mungkin bukan yang terbaik untuk disimpan. FF / Gecko mendefinisikan RegExp sebagai perpanjangan dari Function.
(FF2 pergi sejauh
typeof(/pattern/) == 'function'
)Tampaknya ini khusus untuk FF - IE, Opera, dan Chrome semua membuang pengecualian untuk itu.
Sebaliknya, gunakan salah satu metode yang sebelumnya disebutkan oleh orang lain:
RegExp#exec
atauString#match
.Mereka menawarkan hasil yang sama:
sumber
Tidak perlu memanggil
exec
metode! Anda dapat menggunakan metode "cocokkan" langsung pada string. Hanya saja, jangan lupa tanda kurung.Posisi 0 memiliki string dengan semua hasil. Posisi 1 memiliki kecocokan pertama diwakili oleh tanda kurung, dan posisi 2 memiliki kecocokan kedua diisolasi dalam tanda kurung Anda. Kurung bersarang itu rumit, jadi waspadalah!
sumber
Satu liner yang praktis hanya jika Anda memiliki sepasang tanda kurung:
sumber
while (match = myRegex.exec(myStr)) matches.push(match[1])
Menggunakan kode Anda:
Sunting: Safari 3, jika itu penting.
sumber
Dengan es2018 Anda sekarang dapat
String.match()
dengan grup yang diberi nama, membuat regex Anda lebih eksplisit dari apa yang ia coba lakukan.dan Anda akan mendapatkan sesuatu seperti
sumber
sumber
Kode Anda berfungsi untuk saya (FF3 pada Mac) bahkan jika saya setuju dengan PhiLo bahwa regex mungkin harus:
(Tapi, tentu saja, aku tidak yakin karena aku tidak tahu konteks dari regex.)
sumber
sumber
Anda tidak benar-benar membutuhkan loop eksplisit untuk mem-parsing beberapa pertandingan - berikan fungsi pengganti sebagai argumen kedua seperti yang dijelaskan dalam
String.prototype.replace(regex, func)
::The
m0
Argumen merupakan substring cocok penuh{0}
,{1}
, dllm1
mewakili kelompok pencocokan pertama, yaitu bagian yang ditutupi dalam kurung dalam regex yang0
untuk pertandingan pertama. Danposition
adalah indeks awal dalam string tempat grup yang cocok ditemukan - tidak digunakan dalam kasus ini.sumber
Dalam kode \ 1 diwakili cocok dengan grup pertama ([az])
sumber
Solusi satu baris:
Jadi Anda bisa menggunakan cara ini (harus menggunakan / g):
hasil:
sumber
Dapatkan semua kejadian kelompok
sumber
Saya Anda seperti saya dan berharap regex akan mengembalikan Obyek seperti ini:
lalu potong fungsi dari bawah
sumber
HANYA MENGGUNAKAN RegExp. $ 1 ... $ n grup mis:
1.Untuk mencocokkan RegExp grup 1 $ 1
jika Anda menggunakan 3 grup di regex likey (perhatikan penggunaan setelah string.match (regex))
RegExp. $ 1 RegExp. $ 2 RegExp. $ 3
sumber