Fitur regular expression mendatang

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

Fitur ini saat ini sedang diusulkan untuk disertakan dalam spesifikasi JavaScript. Meskipun 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 desain dan penerapan yang tepat waktu kepada penulis proposal masing-masing sebelum spesifikasi diselesaikan.

Postingan blog ini memberi Anda pratinjau masa depan yang menarik ini. Jika Anda ingin mengikuti contoh mendatang, aktifkan fitur JavaScript eksperimental di chrome://flags/#enable-javascript-harmony.

Rekaman bernama

Ekspresi reguler dapat berisi tangkapan (atau grup) yang disebut, yang dapat mengambil sebagian teks yang cocok. Sejauh ini, developer hanya dapat merujuk ke pengambilan ini berdasarkan indeksnya, yang ditentukan oleh posisi pengambilan 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 sudah terkenal sulit dibaca, ditulis, dan dipertahankan, dan referensi numerik dapat menambah kerumitan lebih lanjut. Misalnya, dalam pola yang lebih panjang, sulit untuk menentukan indeks pengambilan tertentu:

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

Lebih buruk lagi, perubahan pada pola berpotensi mengubah indeks semua rekaman yang ada:

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

Rekaman bernama adalah fitur mendatang yang membantu memitigasi masalah ini dengan memungkinkan developer menetapkan nama ke rekaman. 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'

Rekaman 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 fitur baru ini tersedia di proposal spesifikasi.

Tanda dotAll

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

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

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

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

Detail lengkap fitur baru ini tersedia di proposal spesifikasi.

Escape properti Unicode

Dengan pengenalan Unicode yang diperkenalkan di ES2015, tiba-tiba ada lebih banyak karakter yang dapat dianggap sebagai angka, misalnya angka satu yang dilingkari: ①; atau dianggap sebagai karakter kata, misalnya karakter bahasa China untuk salju: 雪.

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

Sebagai gantinya, urutan escape properti baru sedang diperkenalkan. Perhatikan bahwa flag ini hanya tersedia untuk ekspresi reguler yang mendukung Unicode yang ditunjukkan oleh 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 lebih banyak properti, 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 dalam proposal spesifikasi saat ini. Untuk contoh lainnya, lihat artikel informatif ini.

Pernyataan lookbehind

Pernyataan lookahead telah menjadi bagian dari sintaksis ekspresi reguler JavaScript sejak awal. Bagian yang setara, pernyataan lookbehind, akhirnya diperkenalkan. Beberapa dari Anda mungkin ingat bahwa ini sudah menjadi bagian dari V8 sejak lama. Kita bahkan menggunakan pernyataan lookbehind di balik layar untuk menerapkan flag Unicode yang ditentukan di ES2015.

Namanya sudah cukup menggambarkan maknanya. Ini menawarkan cara untuk membatasi pola agar hanya cocok jika didahului oleh pola dalam grup lookbehind. Fitur 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 yang ditujukan untuk pernyataan lookbehind, 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 mewujudkannya: terutama pakar bahasa Mathias Bynens, Dan Ehrenberg, Claude Pache, Brian Terlson, Thomas Wood, Gorkem Yakin, dan guru Irregexp Erik Corry; tetapi juga semua orang yang telah berkontribusi pada spesifikasi bahasa dan implementasi V8 terhadap fitur ini.

Kami harap Anda juga menyukai fitur ekspresi reguler baru ini seperti kami.