Saya mencoba menguraikan jenis string berikut:
[key:"val" key2:"val2"]
di mana ada kunci acak: pasangan "val" di dalamnya. Saya ingin mengambil nama kunci dan nilainya. Bagi mereka yang penasaran, saya mencoba mem-parsing format database task warrior.
Inilah string pengujian saya:
[description:"aoeu" uuid:"123sth"]
yang dimaksudkan untuk menyoroti bahwa apa pun bisa menjadi kunci atau nilai selain dari ruang, tidak ada ruang di sekitar titik dua, dan nilai selalu dalam tanda kutip ganda.
Dalam simpul, ini adalah output saya:
[deuteronomy][gatlin][~]$ node
> var re = /^\[(?:(.+?):"(.+?)"\s*)+\]$/g
> re.exec('[description:"aoeu" uuid:"123sth"]');
[ '[description:"aoeu" uuid:"123sth"]',
'uuid',
'123sth',
index: 0,
input: '[description:"aoeu" uuid:"123sth"]' ]
Tetapi description:"aoeu"
juga cocok dengan pola ini. Bagaimana saya bisa mendapatkan semua pertandingan kembali?
javascript
regex
regex-group
taskwarrior
Gatlin
sumber
sumber
"some string".match(/regex/g)
Jawaban:
Lanjutkan menelepon
re.exec(s)
dalam satu lingkaran untuk mendapatkan semua kecocokan:Cobalah dengan JSFiddle ini: https://jsfiddle.net/7yS2V/
sumber
while
bukando … while
?while(m = re.exec(s))
, yang merupakan IMO anti-pola, atau Anda harus menulism = re.exec(s); while (m) { ... m = re.exec(s); }
. Saya lebih sukado ... if ... while
idiom, tetapi teknik lain juga akan berhasil.g
mengatur flag, jika tidak pointer internal tidak akan bergerak maju Documents .str.match(pattern)
, jikapattern
memiliki bendera globalg
, akan mengembalikan semua kecocokan sebagai array.Sebagai contoh:
sumber
"All of us except @Emran:emran26, @Raju:raju13 and @Noman:noman42".match(/@(\w+):(\w+)/g)
(yang akan kembali["@Emran:emran26", "@Raju:raju13", "@Noman:noman42"]
)/@\w/g
ataunew RegExp("@\\w", "g")
Untuk mengulang semua pertandingan, Anda dapat menggunakan
replace
fungsi:sumber
Ini solusinya
Ini didasarkan pada jawaban lawnsea, tetapi lebih pendek.
Perhatikan bahwa flag `g 'harus diatur untuk menggerakkan pointer internal ke depan di seluruh permintaan.
sumber
mengembalikan semua kecocokan sebagai sebuah array.
Jika, karena alasan misterius, Anda memerlukan informasi tambahan yang disertakan
exec
, sebagai alternatif dari jawaban sebelumnya, Anda dapat melakukannya dengan fungsi rekursif alih-alih loop sebagai berikut (yang juga terlihat lebih keren).seperti yang dinyatakan dalam komentar sebelumnya, penting untuk memiliki
g
pada akhir definisi regex untuk menggerakkan pointer ke depan dalam setiap eksekusi.sumber
Kami akhirnya mulai melihat
matchAll
fungsi bawaan, lihat di sini untuk tabel deskripsi dan kompatibilitas . Sepertinya pada Mei 2020, Chrome, Edge, Firefox, dan Node.js (12+) didukung tetapi tidak untuk IE, Safari, dan Opera. Sepertinya itu dirancang pada Desember 2018 jadi beri waktu untuk menjangkau semua browser, tapi saya percaya itu akan sampai di sana.Built-in
matchAll
fungsi baik karena mengembalikan sebuah iterable . Ini juga mengembalikan grup penangkap untuk setiap pertandingan! Jadi Anda bisa melakukan hal-hal sepertiSepertinya setiap objek pertandingan menggunakan format yang sama dengan
match()
. Jadi setiap objek adalah array dari pertandingan dan menangkap kelompok, bersama dengan tiga sifat tambahanindex
,input
dangroups
. Jadi sepertinya:Untuk informasi lebih lanjut tentang
matchAll
ada juga halaman pengembang Google . Ada juga polyfill / shims yang tersedia.sumber
Berdasarkan fungsi Agus, tapi saya lebih suka mengembalikan nilai kecocokan:
sumber
Iterables lebih baik:
Penggunaan dalam satu lingkaran:
Atau jika Anda menginginkan array:
sumber
if (m)
should beif (match)
matchAll
yang mengembalikan iterable : DJika Anda memiliki ES9
(Artinya jika sistem Anda: Chrome, Node.js, Firefox, dll mendukung Ecmascript 2019 atau lebih baru)
Gunakan yang baru
yourString.matchAll( /your-regex/ )
.Jika Anda tidak memiliki ES9
Jika Anda memiliki sistem yang lebih lama, inilah fungsi untuk menyalin dan menempel dengan mudah
contoh penggunaan:
output:
sumber
Inilah fungsi saya untuk mendapatkan kecocokan:
sumber
Sejak ES9, sekarang ada cara yang lebih sederhana dan lebih baik untuk mendapatkan semua pertandingan, bersama dengan informasi tentang kelompok tangkap, dan indeks mereka:
Saat ini didukung di Chrome, Firefox, Opera. Bergantung pada saat Anda membaca ini, periksa tautan ini untuk melihat dukungannya saat ini.
sumber
g
dan itulastIndex
harus diatur ulang ke 0 sebelum doamatchAll
.Gunakan ini...
Ini akan mengembalikan array semua pertandingan ... Itu akan bekerja dengan baik .... Tapi ingat itu tidak akan mengambil kelompok dalam akun .. Itu hanya akan mengembalikan pertandingan penuh ...
sumber
Saya pasti akan merekomendasikan menggunakan fungsi String.match (), dan membuat RegEx yang relevan untuk itu. Contoh saya adalah dengan daftar string, yang sering diperlukan saat memindai input pengguna untuk kata kunci dan frasa.
Semoga ini membantu!
sumber
Ini sebenarnya tidak akan membantu masalah Anda yang lebih rumit, tetapi saya tetap mempostingnya karena ini adalah solusi sederhana untuk orang-orang yang tidak melakukan pencarian global seperti Anda.
Saya telah menyederhanakan regex dalam jawaban agar lebih jelas (ini bukan solusi untuk masalah Anda yang sebenarnya).
Yang terlihat lebih bertele-tele daripada karena komentar, ini seperti apa tanpa komentar
Perhatikan bahwa grup apa pun yang tidak cocok akan terdaftar dalam array sebagai
undefined
nilai.Solusi ini menggunakan operator penyebaran ES6 untuk memurnikan array nilai spesifik regex. Anda perlu menjalankan kode Anda melalui Babel jika Anda menginginkan dukungan IE11.
sumber
Inilah solusi satu baris tanpa loop sementara .
Urutan disimpan dalam daftar yang dihasilkan.
Kerugian potensial adalah
sumber
Dugaan saya adalah bahwa jika akan ada kasus tepi seperti ruang ekstra atau hilang, ungkapan ini dengan batas kurang mungkin juga menjadi pilihan:
Uji
Sirkuit RegEx
jex.im memvisualisasikan ekspresi reguler:
sumber
Inilah jawaban saya:
sumber
str
) memiliki format yang salah (terlalu banyak tanda kurung keras). Anda hanya menangkap kunci, bukan nilainya. Kode Anda memiliki kesalahan sintaks dan dan tidak mengeksekusi (kurung terakhir). Jika Anda menjawab pertanyaan "lama" dengan jawaban yang sudah diterima, pastikan Anda menambahkan lebih banyak pengetahuan dan jawaban yang lebih baik daripada yang sudah diterima. Saya tidak berpikir jawaban Anda melakukan itu.