Fitur regular expression mendatang

Jakob Gruber
Yang Guo

ES2015 memperkenalkan banyak fitur baru ke bahasa JavaScript, termasuk peningkatan signifikan pada sintaksis ekspresi reguler dengan flag Unicode (/u) dan melekat (/y). Namun, pengembangan tidak berhenti sejak saat itu. Melalui kolaborasi erat dengan anggota lain di TC39 (isi standar ECMAScript), tim V8 telah mengusulkan dan mendesain bersama beberapa fitur baru untuk membuat ekspresi reguler menjadi lebih canggih.

Fitur ini sedang diusulkan untuk disertakan dalam spesifikasi JavaScript. Meskipun proposal belum sepenuhnya disetujui, proposal tersebut sudah berada di Tahap 3 dalam proses TC39. Kami telah menerapkan fitur ini di balik tanda (lihat di bawah) agar dapat memberikan masukan terkait desain dan implementasi yang tepat waktu kepada setiap penulis proposal sebelum spesifikasi diselesaikan.

Postingan blog ini memberikan gambaran tentang masa depan yang menarik ini. Jika Anda ingin mengikuti contoh yang akan datang, aktifkan fitur JavaScript eksperimental di chrome://flags/#enable-javascript-harmony.

Screenshot bernama

Ekspresi reguler dapat berisi apa yang disebut tangkapan (atau grup), yang dapat menangkap sebagian teks yang cocok. Sejauh ini, developer hanya dapat merujuk ke tangkapan ini berdasarkan indeksnya, yang ditentukan oleh posisi tangkapan dalam pola.

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-07-10');
// result[0] === '2017-07-10'
// result[1] === '2017'
// result[2] === '07'
// result[3] === '10'

Namun, ekspresi reguler terkenal sangat sulit untuk dibaca, ditulis, dan dipelihara, dan referensi numerik dapat menambah detail lebih lanjut. Misalnya, dalam pola yang lebih panjang, mungkin sulit untuk menentukan indeks tangkapan tertentu:

/(?:(.)(.(?<=[^(])(.)))/  // Index of the last capture?

Dan lebih buruk lagi, perubahan pada suatu pola berpotensi menggeser indeks dari semua tangkapan yang ada:

/(a)(b)(c)\3\2\1/     // A few simple numbered backreferences.
/(.)(a)(b)(c)\4\3\2/  // All need to be updated.

Tangkapan bernama adalah fitur mendatang yang membantu mengurangi masalah ini dengan memungkinkan developer menetapkan nama untuk tangkapan. Sintaksisnya mirip dengan Perl, Java, .Net, dan Ruby:

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2017-07-10');
// result.groups.year === '2017'
// result.groups.month === '07'
// result.groups.day === '10'

Tangkapan bernama juga dapat direferensikan oleh referensi balik bernama dan melalui String.prototype.replace:

// Named backreferences.
/(?<LowerCaseX>x)y\k<LowerCaseX>/.test('xyx');  // true

// String replacement.
const pattern = /(?<fst>a)(?<snd>b)/;
'ab'.replace(pattern, '$<snd>$<fst>');                              // 'ba'
'ab'.replace(pattern, (m, p1, p2, o, s, {fst, snd}) => fst + snd);  // 'ba'

Detail lengkap tentang fitur baru ini tersedia di proposal spesifikasi.

flag dotAll

Secara default, atom . dalam ekspresi reguler cocok dengan karakter apa pun kecuali untuk terminator baris:

/foo.bar/u.test('foo\nbar');   // false

Proposal memperkenalkan mode dotAll, yang diaktifkan melalui tanda /s. Dalam mode dotAll, . juga cocok dengan terminal baris.

/foo.bar/su.test('foo\nbar');  // true

Detail lengkap tentang fitur baru ini tersedia di proposal spesifikasi.

Escape properti unicode

Dengan kesadaran Unicode yang diperkenalkan pada ES2015, tiba-tiba ada banyak karakter lainnya yang dapat dianggap sebagai angka, misalnya angka satu yang dilingkari: 1; atau karakter kata yang dianggap, misalnya karakter bahasa China untuk salju: 雪.

Tidak satu pun yang dapat dicocokkan dengan \d atau \w. Mengubah makna singkatan ini akan merusak pola ekspresi reguler yang ada.

Sebagai gantinya, urutan escape properti yang baru sedang diperkenalkan. Perhatikan bahwa parameter tersebut hanya tersedia untuk ekspresi reguler berbasis Unicode yang dilambangkan dengan flag /u.

/\p{Number}/u.test('①');      // true
/\p{Alphabetic}/u.test('雪');  // true

Invers dapat dicocokkan dengan \P.

/\P{Number}/u.test('①');      // false
/\P{Alphabetic}/u.test('雪');  // false

Konsorsium Unicode menentukan banyak properti lainnya, misalnya untuk simbol matematika atau karakter Hiragana Jepang:

/^\p{Math}+$/u.test('∛∞∉');                            // true
/^\p{Script_Extensions=Hiragana}+$/u.test('ひらがな');  // true

Daftar lengkap class properti Unicode yang didukung dapat ditemukan di proposal spesifikasi saat ini. Untuk contoh lainnya, lihat artikel informatif ini.

Lihat di balik pernyataan

Pernyataan pandangan ke depan telah menjadi bagian dari sintaksis ekspresi reguler JavaScript sejak awal. Pasangannya, yakni pernyataan di balik layar, akhirnya diperkenalkan. Beberapa dari Anda mungkin ingat bahwa ini telah menjadi bagian dari V8 cukup lama. Kami bahkan menggunakan pernyataan cari di balik layar untuk mengimplementasikan flag Unicode yang ditentukan dalam ES2015.

Nama tersebut sudah menjelaskan artinya dengan cukup baik. Fitur ini menawarkan cara untuk membatasi pola agar hanya dicocokkan jika didahului oleh pola dalam grup Lookbehind. ID ini tersedia dalam ragam yang cocok dan tidak cocok:

/(?<=\$)\d+/.exec('$1 is worth about ¥123');  // ['1']
/(?<!\$)\d+/.exec('$1 is worth about ¥123');  // ['123']

Untuk mengetahui detail selengkapnya, lihat postingan blog sebelumnya kami yang khusus untuk memeriksa pernyataan dan contoh dalam kasus pengujian V8 terkait.

Ucapan terima kasih

Postingan blog ini tidak akan lengkap tanpa menyebutkan beberapa orang yang telah bekerja keras untuk mewujudkan hal ini: terutama juara bahasa Mathias Bynens, Dan Ehrenberg, Claude Pache, Brian Terlson, Thomas Wood, Gorkem Yakin, dan guru Irregexp Erik Corry; dan juga semua orang yang telah berkontribusi terhadap spesifikasi bahasa ini.

Semoga Anda sama antusiasnya dengan fitur ekspresi reguler baru ini, seperti kami.