Menu

Regex JavaScript: test, match, replace, dan Capture Group

Cara kerja regular expression di JavaScript: membuat pola, method inti (test, match, replace), flag, dan capture group dengan contoh nyata.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Regex adalah pola untuk mencocokkan teks

Regular expression menggambarkan bentuk string: "empat digit," "sebuah kata yang diikuti koma," "apa pun yang terlihat seperti email." JavaScript memberimu dua cara untuk membuatnya:

Bentuk literal, yaitu garis miring di sekitar pola dengan flag setelah garis miring penutup, adalah yang paling sering kamu pakai. Pakai new RegExp(...) saat polanya sendiri dinamis, misalnya disusun dari input pengguna atau sebuah variabel.

Huruf i di ujung adalah flag. i berarti tidak membedakan huruf besar dan kecil. Penjelasan tentang flag sebentar lagi.

test: apakah cocok?

Pertanyaan tercepat yang bisa kamu ajukan ke regex adalah "apakah string ini mengandung kecocokan?" Itulah test:

\d berarti "digit apa saja." test mengembalikan true atau false dan tidak lebih. Kalau yang kamu butuhkan hanya jawaban ya atau tidak, misalnya memvalidasi field atau memfilter array, test adalah alat yang tepat.

match: mengambil teks yang cocok

Saat kamu menginginkan teks yang cocok itu sendiri, pakai method match milik string:

Tanpa flag g, match mengembalikan array berisi kecocokan pertama beserta metadata (index, input). Dengan g, ia mengembalikan setiap kecocokan sebagai array string biasa. Kalau tidak ada yang cocok, kamu mendapat null, bukan array kosong, jadi lindungi kodemu:

Flag mengubah perilaku pola

Flag ditulis setelah garis miring penutup dan mengubah cara pencocokan bekerja. Yang paling sering kamu pakai:

  • g: global, temukan setiap kecocokan, bukan hanya yang pertama.
  • i: tidak membedakan huruf besar dan kecil.
  • m: multiline, sehingga ^ dan $ cocok dengan awal/akhir baris, bukan hanya awal/akhir string.
  • s: dotall, sehingga . juga cocok dengan baris baru.
  • u: sadar unicode, dibutuhkan untuk banyak pola emoji dan non-ASCII.

Tanpa m, ^ hanya menambat ke awal string yang paling depan. Dengan m, ia menambat ke awal setiap baris, jadi Roses dan Violets sama-sama tertangkap.

Character class dan quantifier

Balok bangunan sebagian besar pola:

  • \d digit, \w karakter kata (huruf/digit/garis bawah), \s whitespace.
  • [abc] salah satu dari a, b, atau c. [^abc] apa pun kecuali itu. [a-z] sebuah rentang.
  • . karakter apa pun kecuali baris baru.
  • * nol atau lebih, + satu atau lebih, ? nol atau satu.
  • {3} tepat tiga, {2,5} antara dua dan lima, {2,} dua atau lebih.
  • ^ awal, $ akhir.

Kalau digabungkan:

\b adalah word boundary, yaitu garis tak terlihat antara karakter kata dan karakter bukan kata. Berguna saat kamu ingin mencocokkan "kata utuh". Untuk melihat apa yang dicocokkan sebuah pola sebelum kamu memakainya di kode, coba di regex tester.

Capture group: mengingat bagian dari kecocokan

Tanda kurung membuat group yang menangkap apa pun yang dicocokkannya. exec dan match mengembalikan hasil tangkapan itu bersama kecocokan keseluruhan:

Indeks 0 adalah kecocokan penuh, dan setiap group mendapat slotnya sendiri sesudahnya. Menghitung group berdasarkan posisi jadi merepotkan begitu jumlahnya lebih dari dua, jadi beri nama:

Group bernama lebih mudah dibaca di tempat pemakaiannya dan tetap aman walaupun urutan polanya diubah.

replace: menulis ulang teks yang cocok

replace menerima pola dan pengganti. Penggantinya bisa berupa string atau fungsi:

Tanpa g, hanya kecocokan pertama yang diganti. Kesalahan yang umum adalah lupa flag-nya lalu bingung kenapa email kedua masih terlihat salah.

String pengganti mendukung back-reference. $1, $2, dan seterusnya merujuk ke capture group; $<name> merujuk ke group bernama:

Untuk apa pun yang lebih dari sekadar substitusi langsung, kirim sebuah fungsi. Fungsi itu menerima kecocokan dan hasil tangkapan sebagai argumen:

Garis bawah adalah kecocokan penuh (yang tidak kita butuhkan); n adalah capture group pertama. Pola ini, regex ditambah fungsi pengganti, menangani sebagian besar pengolahan teks di dunia nyata.

matchAll: setiap kecocokan beserta group-nya

String.prototype.matchAll mengembalikan iterator berisi setiap kecocokan beserta capture group-nya, sesuatu yang tidak bisa dilakukan match biasa dengan flag g:

matchAll wajib memakai flag g. Tanpanya, kamu akan mendapat TypeError. Spread hasilnya ke array ([...text.matchAll(email)]) kalau kamu butuh akses acak, bukan perulangan.

Escape karakter khusus

Karakter seperti . * + ? ( ) [ ] { } | \ ^ $ punya arti khusus di regex. Untuk mencocokkannya secara harfiah, escape dengan backslash:

Versi yang tidak di-escape cocok dengan examplexcom karena . berarti "karakter apa pun." Bug semacam ini umum, dan tidak terlihat. Kalau sebuah regex mencocokkan terlalu banyak, cari dulu . yang tidak di-escape.

Saat menyusun pola dari input pengguna, kamu wajib meng-escape-nya, atau pengguna bisa menyisipkan sintaks regex:

$& dalam string pengganti adalah singkatan dari "seluruh kecocokan."

Lookahead dan lookbehind

Kadang kamu ingin mencocokkan teks hanya kalau ia diikuti (atau didahului) sesuatu, tanpa memasukkan sesuatu itu ke dalam kecocokan. Itulah fungsi lookaround:

  • (?= ...) lookahead positif: "diikuti oleh."
  • (?<= ...) lookbehind positif: "didahului oleh."
  • (?! ...) dan (?<! ...) adalah versi negatifnya.

Lookaround tidak memakan karakter, jadi bagian yang sedang "dilihat" tetap tersedia untuk bagian pola berikutnya.

Sedikit soal validasi email

Kamu akan sering menemui permintaan ini: "berikan regex untuk memvalidasi email." Jawaban jujurnya: jangan. Tata bahasa email yang sebenarnya rumit, dan regex apa pun yang cukup pendek untuk dibaca pasti salah ke salah satu arah. Untuk validasi form, pola yang pragmatis sudah cukup:

Bacalah seperti ini: "beberapa karakter yang bukan whitespace dan bukan @, sebuah @, lalu karakter sejenis lagi, sebuah titik, lalu karakter sejenis lagi." Pola itu menangkap salah ketik yang jelas tanpa berpura-pura menegakkan RFC 5322. Untuk verifikasi sungguhan, kirim email konfirmasi.

Kesalahan umum

Beberapa jebakan yang perlu kamu pahami betul:

  • Lupa g pada replace atau matchAll. Hanya kecocokan pertama, atau TypeError.
  • lastIndex yang menyimpan state pada regex global. Regex dengan flag g atau y mengingat di mana ia terakhir berhenti di antara pemanggilan test/exec. Jangan memakai ulang satu regex untuk string-string yang tidak berhubungan; buat yang baru, atau pakai matchAll.
  • Titik dan garis miring yang tidak di-escape pada pola dinamis. Selalu escape input pengguna sebelum memasukkannya ke new RegExp(...).
  • Catastrophic backtracking. Quantifier bersarang seperti (a+)+ pada input yang ekstrem bisa membekukan tab. Kalau sebuah regex terasa lambat, sederhanakan.

Berikutnya: tanggal dan waktu

Regex menangani bentuk teks; data nyata juga datang dengan timestamp yang perlu di-parse, diformat, dan dihitung. Halaman berikutnya membahas Date, Intl.DateTimeFormat, dan cara berpikir yang menjauhkan bug zona waktu.

Pertanyaan yang sering diajukan

Bagaimana cara membuat regex di JavaScript?

Ada dua cara. Bentuk literal memakai garis miring: /hello/i. Constructor menerima string: new RegExp('hello', 'i'). Pakai literal saat polanya tetap, dan constructor saat kamu perlu menyusun pola dari variabel saat runtime.

Apa bedanya test, match, dan exec pada regex JavaScript?

regex.test(str) mengembalikan boolean, paling cepat saat kamu hanya peduli apakah ada kecocokan. str.match(regex) mengembalikan array berisi kecocokan (atau null). regex.exec(str) mengembalikan satu kecocokan per pemanggilan beserta capture group-nya, dan dengan flag g, ia melacak posisi di antara pemanggilan lewat lastIndex.

Bagaimana cara mengganti semua kemunculan dengan regex di JavaScript?

Pakai flag g: str.replace(/foo/g, 'bar'). Tanpa g, hanya kecocokan pertama yang diganti. Kamu juga bisa memanggil str.replaceAll(/foo/g, 'bar'), tapi replaceAll dengan argumen regex wajib memakai flag g; kalau tidak, ia melempar error.

Apa itu capture group pada regex JavaScript?

Tanda kurung dalam pola membuat capture group yang mengingat apa yang dicocokkannya. /(\d{4})-(\d{2})/.exec('2024-11') mengembalikan array dengan indeks 1 berisi '2024' dan indeks 2 berisi '11'. Beri nama dengan (?<year>\d{4}) dan akses lewat match.groups.year.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai