Dua regex yang pattern-nya sama persis bisa berperilaku berbeda. Yang satu berhenti pada kecocokan pertama, yang lain mengumpulkan semuanya; yang satu peduli huruf kapital, yang lain tidak. Pengatur perilaku itu disebut flag: huruf tambahan yang ditulis setelah garis miring penutup. /kopi/ dan /kopi/g adalah dua regex object dengan karakter pattern yang sama tetapi aturan kerja yang berbeda.
| Flag | Nama | Efek |
|---|---|---|
g | global | Mencari semua kecocokan, bukan berhenti di yang pertama |
i | ignore case | Tidak peduli huruf besar-kecil |
m | multiline | ^ dan $ berlaku pada tiap baris |
s | dotAll | Titik . ikut mencocokkan baris baru |
u | unicode | Pattern membaca satu code point secara utuh |
y | sticky | Hanya mencocokkan tepat di posisi lastIndex |
Flag juga dapat digabung: /kopi/gi sekaligus mencari semua kecocokan tanpa memedulikan kapitalisasi. Kita mulai dari flag yang paling sering dipakai sekaligus paling sering mengejutkan: g.
Flag g dan Properti lastIndex #
Aturan flag g: regex tidak berhenti pada kecocokan pertama. Konsekuensinya, method exec() yang biasa mengulang jawaban yang sama kini bergerak maju — setiap pemanggilan memulai pencarian dari posisi yang tersimpan di properti lastIndex milik regex object, lalu memperbarainya setelah selesai.
Berkas berikut memanggil exec() berulang kali pada regex yang sama dan mencetak posisi kecocokan beserta lastIndex-nya:
// uji-flag.js
// Mengamati bagaimana flag g menggerakkan properti lastIndex.
const log = "stok kopi, stok teh, stok gula";
const pola = /stok/g;
// 1. Setiap exec mulai mencari dari posisi lastIndex
let hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
// 2. Kehabisan kecocokan: exec mengembalikan null, lastIndex kembali ke 0
hasil = pola.exec(log);
console.log(hasil);
console.log(pola.lastIndex);
// 3. Loop while: pola idiomatik membaca semua kecocokan
const polaLanjut = /stok/g;
let temuan;
while ((temuan = polaLanjut.exec(log)) !== null) {
console.log(temuan[0], "di indeks", temuan.index);
}
console.log(temuan, polaLanjut.lastIndex);Output yang Dihasilkan:
stok indeks 0 | lastIndex 4
stok indeks 11 | lastIndex 15
stok indeks 21 | lastIndex 25
null
0
stok di indeks 0
stok di indeks 11
stok di indeks 21
null 0Jalankan dengan node uji-flag.js dan cocokkan hasilnya. Mari kita telaah baris-baris pentingnya:
- Baris 8 (
pola.exec(log)): kecocokan pertama “stok” ditemukan pada indeks 0, danlastIndexmelompat ke4— tepat setelah kata tersebut. - Baris 10 dan 12: dua pemanggilan berikutnya tidak mulai dari awal; keduanya meneruskan dari
lastIndexdan menemukan kecocokan di indeks11dan21. - Baris 16–18: kehabisan kecocokan membuat
exec()mengembalikannull, lalulastIndexotomatis kembali ke0— regex siap memulai dari awal lagi. - Baris 23 (
while ((temuan = polaLanjut.exec(log)) !== null)): bentuk idiomatik membaca semua kecocokan; hasil assignment dipakai sebagai kondisi, sehingga loop berhenti tepat saatexec()mengembalikannull. - Baris 26: bukti penutup — setelah loop selesai,
temuanbernilainulldanlastIndexkembali0.
Cara yang lebih ringkas untuk mengumpulkan semua kecocokan adalah match dengan flag g atau matchAll dari chapter Searching Strings. Perbedaannya: keduanya mengumpulkan hasil sekaligus tanpa menyimpan posisi di antara pemanggilan, sehingga tidak menimbulkan efek lastIndex.
Flag i: Mengabaikan Huruf Besar-Kecil #
Flag i memerintahkan pencarian tanpa memedulikan kapitalisasi — tebalik dari perilaku bawaan yang peka huruf:
console.log(/budi/.test("Datang ke acara Budi"));
console.log(/budi/i.test("Datang ke acara Budi"));
console.log("Budi dan budi".match(/budi/gi));Output yang Dihasilkan:
false
true
[ 'Budi', 'budi' ]Tanpa i, kata “Budi” kapital tidak cocok dengan pattern /budi/. Dengan i, keduanya cocok — dan baris ketiga memperlihatkan penggabungan dua flag: g mengumpulkan semua kecocokan, i menyamakan perlakuan huruf.
Dua hal perlu diingat tentang flag i. Pertama, ia berlaku untuk seluruh pattern, bukan sebagian — tidak ada cara memilih satu huruf saja yang boleh kapital melalui flag; bila kebutuhannya seperti itu, daftarkan pilihannya di dalam character class, misalnya [Bb]udi. Kedua, efeknya paling terasa pada data yang ditulis manusia — nama, judul, dan isi pesan — karena kapitalisasi di sana tidak pernah seragam.
Flag m dan s: Baris Baru #
String boleh memuat banyak baris, dan teks seperti itu menimbulkan dua pertanyaan: di mana batas “awal string”? dan apakah titik . menjangkaunya? Flag m menjawab yang pertama — ^ dan $ berlaku pada awal dan akhir tiap baris, bukan hanya awal dan akhir string. Flag s menjawab yang kedua — titik ikut mencocokkan baris baru.
const daftar = "kopi: 12000\nteh: 8000\ngula: 14000";
console.log(/^teh/.test(daftar));
console.log(/^teh/m.test(daftar));Output yang Dihasilkan:
false
trueTanpa m, ^ hanya cocok di posisi nol — dan string itu dimulai dengan “kopi”, bukan “teh”. Dengan m, baris kedua yang dimulai “teh” juga dianggap awal, sehingga hasilnya true.
const memo = "Judul: Reunion Keluarga\nIsi: sampai jumpa";
console.log(/Judul.*Isi/.test(memo));
console.log(/Judul.*Isi/s.test(memo));Output yang Dihasilkan:
false
trueTanpa s, titik berhenti di garis batas baris baru sehingga .* tidak mampu menjangkau dari “Judul” sampai “Isi”. Dengan s, kedua kata itu terhubung meskipun berada di baris berbeda.
Flag u: Satu Code Point #
JavaScript menyimpan string sebagai rangkaian code unit UTF-16. Karakter Latin biasa menempati satu code unit, tetapi banyak karakter non-Latin — emoji misalnya — menempati dua. Tanpa flag u, elemen pattern seperti titik hanya mencocokkan satu code unit; dengan u, pattern membaca satu code point secara utuh.
Flag u juga mengubah cara pattern membaca escape di atas satu code unit, sehingga bila data kita memuat karakter non-Latin dan perilaku pencariannya terasa tidak konsisten, flag ini yang pertama dicoba.
console.log(/^.$/.test("👍"));
console.log(/^.$/u.test("👍"));Output yang Dihasilkan:
false
trueEmoji itu tersimpan sebagai dua code unit, sehingga /^.$/ tanpa u gagal — titik hanya melihat setengah karakter. Dengan u, regex menghitungnya sebagai satu karakter utuh dan pola cocok.
Flag y: Hanya di Posisi lastIndex #
Flag y (sticky) menuntut kecocokan dimulai tepat di posisi lastIndex — regex tidak boleh memindai maju mencari kecocokan di posisi lain. Ia mirip flag g dalam hal memakai lastIndex, tetapi jauh lebih ketat:
const polaLengket = /[0-9]+/y;
polaLengket.lastIndex = 3;
console.log(polaLengket.exec("abc123")[0]);
polaLengket.lastIndex = 2;
console.log(polaLengket.exec("abc123"));Output yang Dihasilkan:
123
nullSaat lastIndex bernilai 3, regex menemukan "123" persis di posisi itu. Saat lastIndex digeser ke 2, karakter pada posisi itu adalah huruf c — dan sticky menolak memindai maju ke angka, sehingga hasilnya null.
Jika dibandingkan berdampingan: flag g mengizinkan exec melompat dari satu kecocokan ke berikutnya, sedangkan flag y menuntut kecocokan berada tepat di tempat yang ditunjuk lastIndex. Keduanya sama-sama menyimpan posisi; yang berbeda adalah seberapa longgar kecocokan boleh dicari.
Enam flag kini sudah lengkap: g mengumpulkan semua kecocokan, i menyamakan huruf, m dan s mengurus baris baru, u membaca code point utuh, dan y menahan pencarian pada satu posisi. Dengan pattern dari chapter sebelumnya dan flag dari chapter ini, kita siap memakai regex untuk tugas paling praktis: memvalidasi format input.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
uji-flag.js
Unduh berkas// uji-flag.js
// Mengamati bagaimana flag g menggerakkan properti lastIndex.
const log = "stok kopi, stok teh, stok gula";
const pola = /stok/g;
// 1. Setiap exec mulai mencari dari posisi lastIndex
let hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
hasil = pola.exec(log);
console.log(hasil[0], "indeks", hasil.index, "| lastIndex", pola.lastIndex);
// 2. Kehabisan kecocokan: exec mengembalikan null, lastIndex kembali ke 0
hasil = pola.exec(log);
console.log(hasil);
console.log(pola.lastIndex);
// 3. Loop while: pola idiomatik membaca semua kecocokan
const polaLanjut = /stok/g;
let temuan;
while ((temuan = polaLanjut.exec(log)) !== null) {
console.log(temuan[0], "di indeks", temuan.index);
}
console.log(temuan, polaLanjut.lastIndex);