Sejauh yang saya tahu tidak ada yang namanya grup penangkap bernama dalam JavaScript. Apa cara alternatif untuk mendapatkan fungsionalitas serupa?
javascript
regex
mmierin
sumber
sumber
Jawaban:
ECMAScript 2018 memperkenalkan kelompok penangkap bernama ke dalam regex JavaScript.
Contoh:
Jika Anda perlu mendukung browser lama, Anda dapat melakukan semuanya dengan grup penangkap normal (bernomor) yang dapat Anda lakukan dengan grup penangkap bernama, Anda hanya perlu melacak angka - yang mungkin rumit jika urutan grup penangkap dalam Anda perubahan regex.
Hanya ada dua keuntungan "struktural" dari kelompok penangkap bernama yang dapat saya pikirkan:
Dalam beberapa rasa regex (.NET dan JGSoft, sejauh yang saya tahu), Anda dapat menggunakan nama yang sama untuk grup yang berbeda di regex Anda ( lihat di sini untuk contoh di mana ini penting ). Tetapi sebagian besar rasa regex tidak mendukung fungsi ini.
Jika Anda perlu merujuk ke grup penangkap bernomor dalam situasi di mana mereka dikelilingi oleh angka, Anda bisa mendapatkan masalah. Katakanlah Anda ingin menambahkan nol ke digit dan karenanya ingin mengganti
(\d)
dengan$10
. Dalam JavaScript, ini akan berfungsi (selama Anda memiliki kurang dari 10 grup yang menangkap di regex Anda), tetapi Perl akan berpikir Anda sedang mencari nomor referensi10
bukan angka1
, diikuti oleh a0
. Di Perl, Anda dapat menggunakan${1}0
dalam hal ini.Selain itu, kelompok penangkap bernama hanya "gula sintaksis". Ini membantu untuk menggunakan grup menangkap hanya ketika Anda benar-benar membutuhkannya dan menggunakan grup yang tidak menangkap
(?:...)
dalam semua keadaan lain.Masalah yang lebih besar (menurut saya) dengan JavaScript adalah bahwa ia tidak mendukung regex verbose yang akan membuat pembuatan ekspresi reguler yang mudah dibaca dan kompleks menjadi jauh lebih mudah.
Pustaka XRegExp Steve Levithan memecahkan masalah ini.
sumber
Anda dapat menggunakan XRegExp , implementasi lintas-reguler dari ekspresi reguler yang diperbesar, dapat diperluas, lintas-browser, termasuk dukungan untuk sintaks tambahan, flag, dan metode:
s
:, untuk membuat dot cocok dengan semua karakter (alias mode dotall atau singleline), danx
, untuk spasi bebas dan komentar (alias mode diperluas).sumber
Solusi lain yang mungkin: buat objek yang berisi nama dan indeks grup.
Kemudian, gunakan tombol objek untuk referensi grup:
Ini meningkatkan keterbacaan / kualitas kode menggunakan hasil dari regex, tetapi bukan keterbacaan dari regex itu sendiri.
sumber
Di ES6 Anda dapat menggunakan array restrukturisasi untuk menangkap grup Anda:
Memperhatikan:
let
melewatkan nilai pertama dari array yang dihasilkan, yang merupakan keseluruhan string yang cocok|| []
setelah.exec()
akan mencegah kesalahan destrukturisasi ketika tidak ada pertandingan (karena.exec()
akan kembalinull
)sumber
String.prototype.match
mengembalikan array dengan: seluruh string yang cocok di posisi 0, lalu grup apa pun setelah itu. Koma pertama mengatakan "lewati elemen di posisi 0"RegExp.prototype.exec
lebihString.prototype.match
di tempat-tempat di mana string mungkinnull
atauundefined
.Pembaruan: Akhirnya berhasil masuk ke dalam JavaScript (ECMAScript 2018)!
Grup penangkap yang dinamai dapat membuatnya menjadi JavaScript segera.
Proposal untuk itu sudah pada tahap 3.
Grup tangkap dapat diberi nama di dalam kurung sudut menggunakan
(?<name>...)
sintaks, untuk nama pengidentifikasi apa pun. Ekspresi reguler untuk kencan kemudian dapat ditulis sebagai/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Setiap nama harus unik dan mengikuti tata bahasa untuk ECMAScript IdentifierName .Grup yang diberi nama dapat diakses dari properti properti grup dari hasil ekspresi reguler. Referensi bernomor untuk grup juga dibuat, seperti halnya untuk grup yang tidak disebutkan namanya. Sebagai contoh:
sumber
let {year, month, day} = ((result) => ((result) ? result.groups : {}))(re.exec('2015-01-02'));
Memberi nama grup yang ditangkap memberikan satu hal: lebih sedikit kebingungan dengan ekspresi reguler yang kompleks.
Ini benar-benar tergantung pada kasus penggunaan Anda, tetapi mungkin pencetakan cukup regex Anda bisa membantu.
Atau Anda bisa mencoba dan mendefinisikan konstanta untuk merujuk ke grup yang Anda tangkap.
Komentar mungkin juga membantu menunjukkan kepada orang lain yang membaca kode Anda, apa yang telah Anda lakukan.
Selebihnya saya harus setuju dengan jawaban Tims.
sumber
Ada perpustakaan node.js bernama bernama-regexp yang bisa Anda gunakan dalam proyek node.js Anda (aktif di browser dengan mengemas perpustakaan dengan browserify atau skrip pengemasan lainnya). Namun, perpustakaan tidak dapat digunakan dengan ekspresi reguler yang berisi grup penangkap tanpa nama.
Jika Anda menghitung kawat penangkap pembuka dalam ekspresi reguler Anda, Anda dapat membuat pemetaan antara grup penangkap yang diberi nama dan grup penangkap yang diberi nomor di regex Anda dan dapat mencampur dan mencocokkan secara bebas. Anda hanya perlu menghapus nama grup sebelum menggunakan regex. Saya telah menulis tiga fungsi yang menunjukkan itu. Lihat inti ini: https://gist.github.com/gbirke/2cc2370135b665eee3ef
sumber
Seperti yang dikatakan Tim Pietzcker , ECMAScript 2018 memperkenalkan kelompok penangkap bernama ke dalam regex JavaScript. Tetapi apa yang saya tidak temukan dalam jawaban di atas adalah bagaimana menggunakan kelompok yang ditangkap nama di regex itu sendiri.
Anda dapat menggunakan nama kelompok yang diambil dengan sintaks ini:
\k<name>
. sebagai contohdan seperti yang dikatakan Forivin , Anda dapat menggunakan grup yang ditangkap di hasil objek sebagai berikut:
sumber
Meskipun Anda tidak dapat melakukan ini dengan JavaScript vanilla, mungkin Anda dapat menggunakan beberapa
Array.prototype
fungsi sepertiArray.prototype.reduce
mengubah kecocokan yang diindeks menjadi yang bernama menggunakan beberapa sihir .Jelas, solusi berikut akan membutuhkan pencocokan agar:
sumber
var assocArray = Regex("hello alex, I am dennis", "hello ({hisName}.+), I am ({yourName}.+)");
RegExp
objek dengan menambahkan fungsi ke prototipe-nya.Tidak punya ECMAScript 2018?
Tujuan saya adalah membuatnya bekerja semirip mungkin dengan yang biasa kami lakukan dengan grup yang disebutkan. Sedangkan dalam ECMAScript 2018 Anda dapat menempatkan
?<groupname>
di dalam grup untuk menunjukkan grup bernama, dalam solusi saya untuk javascript yang lebih lama, Anda dapat menempatkan(?!=<groupname>)
di dalam grup untuk melakukan hal yang sama. Jadi ini adalah seperangkat kurung tambahan dan tambahan!=
. Cukup dekat!Saya membungkus semuanya menjadi fungsi prototipe string
fitur
Instruksi
(?!={groupname})
di dalam setiap grup yang ingin Anda beri nama()
dengan menempatkan?:
di awal kelompok itu. Ini tidak akan disebutkan namanya.arrays.js
pemakaian
hasil o
sumber