Regex

Regex #

Regex (Regular Expression) adalah bahasa mini untuk mendeskripsikan pola teks — sesuatu yang jauh lebih ekspresif dari pencarian string biasa, tapi juga jauh lebih mudah salah tulis jika tidak dipahami dengan baik. PHP menggunakan pustaka PCRE (Perl Compatible Regular Expressions) yang merupakan salah satu implementasi regex paling kaya fitur — mendukung capturing group, named group, lookahead, lookbehind, dan banyak lagi. Menguasai regex di PHP bukan tentang menghafal semua sintaksnya — melainkan memahami pola-pola yang paling sering muncul: validasi email dan nomor telepon, ekstraksi data dari HTML atau teks bebas, penggantian teks dengan logika, dan pemisahan string dengan kondisi kompleks. Artikel ini membahas semua itu dari dasar hingga fitur lanjutan yang benar-benar berguna di kode nyata.

Anatomi Pola Regex PHP #

Pola regex PHP selalu dibungkus oleh delimiter — karakter pembatas yang menandai awal dan akhir pola. Delimiter yang paling umum adalah /, tapi karakter lain seperti #, ~, atau @ juga valid — berguna jika pola mengandung banyak / agar tidak perlu di-escape.

/pola/modifier
#pola#modifier
~pola~i
<?php
// Delimiter /
preg_match('/hello/', 'hello world');

// Delimiter # — berguna saat pola mengandung banyak /
preg_match('#https?://[^/]+/#', 'https://example.com/path/');

// Delimiter ~ — untuk pola yang mengandung # (komentar)
preg_match('~\d+~', 'ada 42 angka');

Elemen Dasar Pola #

Karakter Literal dan Meta-karakter #

Karakter biasa cocok dengan dirinya sendiri: a b c 1 2 3
Meta-karakter punya arti khusus:  . ^ $ * + ? { } [ ] \ | ( )
Untuk cocokkan meta-karakter secara literal, escape dengan \: \. \* \+ \?
<?php
// Karakter literal
preg_match('/php/', 'belajar php');        // cocok

// Titik (.) — cocok dengan SATU karakter apapun kecuali newline
preg_match('/p.p/', 'php');                // cocok — p + apapun + p
preg_match('/p.p/', 'pap');                // cocok
preg_match('/p.p/', 'pp');                 // tidak cocok — butuh satu karakter di tengah

// Escape meta-karakter
preg_match('/3\.14/', '3.14');             // cocok — titik literal
preg_match('/3\.14/', '3X14');             // tidak cocok

Character Class [...] #

Character class mencocokkan tepat satu karakter dari sekumpulan yang didefinisikan:

<?php
// [abc] — cocok dengan 'a', 'b', atau 'c'
preg_match('/[aeiou]/', 'hello');           // cocok — 'e' adalah vokal

// [a-z] — rentang karakter
preg_match('/[a-z]/', 'Hello');             // cocok — 'e', 'l', 'l', 'o'
preg_match('/[A-Z]/', 'Hello');             // cocok — 'H'
preg_match('/[0-9]/', 'abc123');            // cocok — '1'
preg_match('/[a-zA-Z0-9]/', 'test');       // cocok — alfanumerik

// [^...] — negasi: karakter yang TIDAK ada dalam set
preg_match('/[^0-9]/', '123abc');          // cocok — 'a' bukan digit
preg_match('/[^a-z]/', 'ABC');             // cocok — 'A' bukan huruf kecil

Shorthand Character Class #

ShorthandSetara denganKeterangan
\d[0-9]Digit
\D[^0-9]Non-digit
\w[a-zA-Z0-9_]Word character (alfanumerik + underscore)
\W[^a-zA-Z0-9_]Non-word character
\s[ \t\n\r\f\v]Whitespace
\S[^ \t\n\r\f\v]Non-whitespace
\bWord boundary (posisi, bukan karakter)
\BNon-word boundary
<?php
// \d — digit
preg_match_all('/\d+/', 'ada 12 apel dan 34 mangga', $m);
// ['12', '34']

// \w — word character
preg_match_all('/\w+/', 'hello world', $m);
// ['hello', 'world']

// \s — whitespace (spasi, tab, newline)
$bersih = preg_replace('/\s+/', ' ', "ada  spasi   berlebih");
// "ada spasi berlebih"

// \b — word boundary
preg_match_all('/\bcat\b/', 'the cat scattered cats', $m);
// ['cat'] — hanya 'cat' yang berdiri sendiri, bukan 'cat' dalam 'scattered' atau 'cats'

preg_match_all('/cat/', 'the cat scattered cats', $m);
// ['cat', 'cat', 'cat'] — tanpa word boundary, semua 'cat' cocok

Anchor — Posisi, Bukan Karakter #

Anchor tidak mencocokkan karakter, tapi mencocokkan posisi di dalam string:

<?php
// ^ — awal string (atau awal baris dengan modifier m)
preg_match('/^PHP/', 'PHP adalah bahasa');   // cocok
preg_match('/^PHP/', 'Belajar PHP');          // tidak cocok — PHP bukan di awal

// $ — akhir string (atau akhir baris dengan modifier m)
preg_match('/php$/', 'belajar php');          // cocok
preg_match('/php$/', 'php adalah bahasa');    // tidak cocok — php bukan di akhir

// ^ dan $ bersama — cocokkan string secara keseluruhan
preg_match('/^\d{5}$/', '12345');             // cocok — tepat 5 digit
preg_match('/^\d{5}$/', '123456');            // tidak cocok — 6 digit
preg_match('/^\d{5}$/', 'abc12');             // tidak cocok — ada huruf

// \A — awal string absolut (tidak terpengaruh modifier m)
// \Z — akhir string absolut sebelum newline opsional
// \z — akhir string absolut
preg_match('/\Aphp\z/i', 'PHP');              // cocok

Quantifier — Berapa Kali Cocok #

Quantifier menentukan berapa kali elemen sebelumnya harus muncul:

QuantifierArti
*0 atau lebih (greedy)
+1 atau lebih (greedy)
?0 atau 1 (greedy)
{n}Tepat n kali
{n,}Minimal n kali
{n,m}Antara n dan m kali
*?0 atau lebih (lazy)
+?1 atau lebih (lazy)
??0 atau 1 (lazy)
<?php
$html = '<b>tebal</b> dan <b>tebal lagi</b>';

// Greedy — cocok sebanyak mungkin
preg_match('/<b>.*<\/b>/', $html, $m);
echo $m[0]; // '<b>tebal</b> dan <b>tebal lagi</b>' — terlalu banyak!

// Lazy (*?) — cocok sesedikit mungkin
preg_match('/<b>.*?<\/b>/', $html, $m);
echo $m[0]; // '<b>tebal</b>' — hanya blok pertama

// preg_match_all dengan lazy
preg_match_all('/<b>.*?<\/b>/', $html, $m);
// ['<b>tebal</b>', '<b>tebal lagi</b>']

// Quantifier konkret
preg_match('/\d{4}/', '2024');          // tepat 4 digit
preg_match('/\d{2,4}/', '123');         // 2-4 digit
preg_match('/\d{3,}/', '12345');        // minimal 3 digit

// Tanda ? untuk opsional
preg_match('/colou?r/', 'color');       // cocok — u opsional
preg_match('/colou?r/', 'colour');      // cocok — u ada

Capturing Group dan Named Group #

Tanda kurung () membuat capturing group — bagian pola yang hasilnya disimpan terpisah dan bisa dirujuk kembali.

<?php
$tanggal = '2024-03-15';

// Group numerik — dirujuk dengan $1, $2, $3 atau \1, \2, \3
preg_match('/(\d{4})-(\d{2})-(\d{2})/', $tanggal, $m);
echo $m[0]; // '2024-03-15' — seluruh match
echo $m[1]; // '2024' — group 1 (tahun)
echo $m[2]; // '03' — group 2 (bulan)
echo $m[3]; // '15' — group 3 (hari)

// Named group — lebih mudah dibaca: (?P<nama>pola)
preg_match('/(?P<tahun>\d{4})-(?P<bulan>\d{2})-(?P<hari>\d{2})/', $tanggal, $m);
echo $m['tahun']; // '2024'
echo $m['bulan']; // '03'
echo $m['hari'];  // '15'

// Gunakan named group dalam replacement
$hasil = preg_replace(
    '/(?P<tahun>\d{4})-(?P<bulan>\d{2})-(?P<hari>\d{2})/',
    '${hari}/${bulan}/${tahun}',
    $tanggal
);
echo $hasil; // '15/03/2024'

// Non-capturing group (?:...) — group tanpa disimpan
// Berguna untuk grouping + quantifier tanpa menggunakan slot capture
preg_match('/(?:https?|ftp):\/\/(\S+)/', 'https://example.com', $m);
echo $m[0]; // 'https://example.com'
echo $m[1]; // 'example.com' — group 1 hanya domain, bukan protokol

Lookahead dan Lookbehind #

Lookahead dan lookbehind mencocokkan posisi berdasarkan apa yang ada di sekitarnya, tanpa mengonsumsi karakter:

<?php
// Lookahead positif (?=...) — cocok jika diikuti pola
// Cari angka yang diikuti " km"
preg_match_all('/\d+(?= km)/', '100 km dan 50 mil', $m);
// ['100'] — hanya '100' yang diikuti ' km', bukan '50'

// Lookahead negatif (?!...) — cocok jika TIDAK diikuti pola
preg_match_all('/\d+(?! km)/', '100 km dan 50 mil', $m);
// ['50'] — '50' tidak diikuti ' km'

// Lookbehind positif (?<=...) — cocok jika didahului pola
// Cari angka yang didahului "Rp "
preg_match_all('/(?<=Rp )\d+/', 'harga Rp 15000 dan Rp 25000', $m);
// ['15000', '25000']

// Lookbehind negatif (?<!...) — cocok jika TIDAK didahului pola
preg_match_all('/\d+(?! km)/', '100 km dan 50 mil', $m);

// Contoh praktis: password validation dengan lookahead
function validasiPassword(string $password): bool
{
    // Minimal 8 karakter
    // Mengandung minimal 1 huruf besar
    // Mengandung minimal 1 digit
    // Mengandung minimal 1 karakter khusus
    return (bool) preg_match(
        '/^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/',
        $password
    );
}

var_dump(validasiPassword('weakpass'));          // false — tidak memenuhi syarat
var_dump(validasiPassword('Kuat123!'));          // true — semua syarat terpenuhi
var_dump(validasiPassword('TanpaAngka!'));       // false — tidak ada digit

Modifier #

Modifier mengubah cara kerja pola secara keseluruhan:

ModifierKeterangan
iCase-insensitive — [a-z] cocok juga dengan [A-Z]
mMultiline — ^ dan $ cocok awal/akhir setiap baris, bukan string
sDotall — . cocok juga dengan newline (\n)
xExtended — whitespace dan #komentar diabaikan, pola bisa multiline
uUnicode — pola dan string diperlakukan sebagai UTF-8
gGlobal — tidak ada di PHP; gunakan preg_match_all()
<?php
$teks = "Halo Dunia\nBelajar PHP";

// i — case-insensitive
preg_match('/php/i', $teks, $m);     // cocok — PHP

// m — multiline
preg_match_all('/^\w+/m', $teks, $m);
// ['Halo', 'Belajar'] — awal setiap baris

// s — dotall
preg_match('/Halo.*PHP/s', $teks, $m);
// cocok — . melewati newline

// x — extended (pola dengan komentar untuk keterbacaan)
$emailPattern = '/
    ^                   # Awal string
    [a-zA-Z0-9._%+-]+  # Username
    @                   # At-sign
    [a-zA-Z0-9.-]+      # Domain name
    \.                  # Titik
    [a-zA-Z]{2,}        # TLD
    $                   # Akhir string
/x';

preg_match($emailPattern, '[email protected]'); // cocok

// u — Unicode/UTF-8
preg_match('/\p{L}+/u', 'héllo wörld', $m);  // \p{L} = Unicode letter
// cocok dengan karakter Unicode

// Gabung beberapa modifier
preg_match('/php/im', $teks); // case-insensitive + multiline

Fungsi PCRE PHP #

preg_match() — Cari Kecocokan Pertama #

<?php
$pola   = '/(\d{4})-(\d{2})-(\d{2})/';
$string = 'Tanggal: 2024-03-15, deadline: 2024-04-30';

// Return 1 jika cocok, 0 jika tidak, false jika error
$hasil = preg_match($pola, $string, $matches, PREG_OFFSET_CAPTURE);

// $matches[0] — seluruh match (dengan posisi jika PREG_OFFSET_CAPTURE)
// $matches[1] — group 1, dst.
var_dump($hasil);   // int(1)
print_r($matches);
// [0] => ['2024-03-15', 9] — nilai dan posisi byte
// [1] => ['2024', 9]
// [2] => ['03', 14]
// [3] => ['15', 17]

// Tanpa PREG_OFFSET_CAPTURE
preg_match($pola, $string, $matches);
echo $matches[1]; // '2024'

preg_match_all() — Cari Semua Kecocokan #

<?php
$html = '<a href="https://google.com">Google</a> dan <a href="https://php.net">PHP</a>';

// Ekstrak semua href dan teks link
preg_match_all('/<a href="([^"]+)">([^<]+)<\/a>/', $html, $matches);

echo $matches[0][0]; // '<a href="https://google.com">Google</a>'
echo $matches[1][0]; // 'https://google.com' — URL
echo $matches[2][0]; // 'Google' — teks
echo $matches[1][1]; // 'https://php.net'
echo $matches[2][1]; // 'PHP'

// Format PREG_SET_ORDER — lebih intuitif untuk diiterasi
preg_match_all('/<a href="([^"]+)">([^<]+)<\/a>/', $html, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
    echo "URL: {$match[1]}, Teks: {$match[2]}\n";
}
// URL: https://google.com, Teks: Google
// URL: https://php.net, Teks: PHP

preg_replace() — Ganti dengan Pola #

<?php
// Penggantian sederhana
$teks  = "harga: 15000 rupiah dan 25000 rupiah";
$hasil = preg_replace('/\d+/', 'N', $teks);
// "harga: N rupiah dan N rupiah"

// Gunakan backreference dalam replacement
$tanggal = '15/03/2024';
$iso     = preg_replace('/(\d{2})\/(\d{2})\/(\d{4})/', '$3-$2-$1', $tanggal);
// '2024-03-15'

// Tambah format ribuan ke semua angka
$kalimat = "beli 1000 apel dan 2500 mangga";
$hasil   = preg_replace('/\d+/', fn($m) => number_format((int)$m[0], 0, ',', '.'), $kalimat);
// Tidak bisa langsung — gunakan preg_replace_callback untuk ini

// Limit jumlah penggantian
$teks   = "cat sat on the mat with a cat";
$hasil  = preg_replace('/cat/', 'dog', $teks, 1); // ganti hanya yang pertama
// "dog sat on the mat with a cat"

preg_replace_callback() — Ganti dengan Logika #

Ketika replacement butuh logika (bukan sekadar string statis), gunakan preg_replace_callback():

<?php
// Ubah semua angka ke format rupiah
$teks  = "laptop seharga 15000000 dan mouse 250000";
$hasil = preg_replace_callback('/\d+/', function(array $m): string {
    return 'Rp ' . number_format((int)$m[0], 0, ',', '.');
}, $teks);
// "laptop seharga Rp 15.000.000 dan mouse Rp 250.000"

// Konversi markdown **tebal** ke <strong>
$markdown = "ini **tebal** dan **sangat tebal** juga";
$html     = preg_replace_callback('/\*\*([^*]+)\*\*/', function(array $m): string {
    return '<strong>' . htmlspecialchars($m[1]) . '</strong>';
}, $markdown);
// "ini <strong>tebal</strong> dan <strong>sangat tebal</strong> juga"

// Dengan arrow function (PHP 7.4+)
$slug = preg_replace_callback('/[A-Z]/', fn($m) => '-' . strtolower($m[0]), 'camelCaseString');
$slug = ltrim($slug, '-');
// "camel-case-string"

preg_split() — Pisahkan dengan Pola #

<?php
// Pisah dengan berbagai delimiter sekaligus
$csv = "apel, mangga;  jeruk|anggur, semangka";
$buah = preg_split('/[\s,;|]+/', $csv, -1, PREG_SPLIT_NO_EMPTY);
// ['apel', 'mangga', 'jeruk', 'anggur', 'semangka']

// PREG_SPLIT_DELIM_CAPTURE — sertakan delimiter dalam hasil
$kalimat = "halo! dunia? ini php.";
$parts   = preg_split('/([!?.])/', $kalimat, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// ['halo', '!', ' dunia', '?', ' ini php', '.']

// Pisah di batas kata
$teks  = "CamelCaseVariableName";
$words = preg_split('/(?=[A-Z])/', $teks, -1, PREG_SPLIT_NO_EMPTY);
// ['Camel', 'Case', 'Variable', 'Name']

preg_grep() — Filter Array #

<?php
// Kembalikan elemen array yang cocok pola
$data = ['apple', 'apricot', 'banana', 'avocado', 'blueberry'];

$dimulaiA = preg_grep('/^a/i', $data);
// [0=>'apple', 1=>'apricot', 3=>'avocado']

// Invert — elemen yang TIDAK cocok
$tidakDimulaiA = preg_grep('/^a/i', $data, PREG_GREP_INVERT);
// [2=>'banana', 4=>'blueberry']

// Validasi array nomor telepon
$nomor = ['08123456789', '0812-3456-789', '+6281234567', 'bukan nomor', '021-1234567'];
$valid = preg_grep('/^(\+62|0)[0-9\-]{9,13}$/', $nomor);
// ['08123456789', '0812-3456-789', '+6281234567', '021-1234567']

Pola Regex Nyata yang Sering Digunakan #

Validasi Input Umum #

<?php
// Email — sederhana yang cukup untuk praktis
function validasiEmail(string $email): bool
{
    return (bool) preg_match('/^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$/', $email);
}
// Catatan: untuk validasi email yang benar-benar akurat, gunakan filter_var()
// filter_var($email, FILTER_VALIDATE_EMAIL)

// Nomor telepon Indonesia
function validasiTeleponIndonesia(string $nomor): bool
{
    // Format: 08xxxxxxxxx atau +628xxxxxxxxx, panjang 10-14 digit
    return (bool) preg_match('/^(\+62|62|0)8[1-9][0-9]{7,10}$/', preg_replace('/[\s\-]/', '', $nomor));
}

// Kode pos Indonesia (5 digit)
function validasiKodePos(string $kode): bool
{
    return (bool) preg_match('/^\d{5}$/', $kode);
}

// NIK (Nomor Induk Kependudukan — 16 digit)
function validasiNIK(string $nik): bool
{
    return (bool) preg_match('/^\d{16}$/', $nik);
}

// URL
function validasiUrl(string $url): bool
{
    return (bool) preg_match('/^https?:\/\/[^\s\/$.?#].[^\s]*$/', $url);
}

// Warna hex (#RGB atau #RRGGBB)
function validasiHex(string $warna): bool
{
    return (bool) preg_match('/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/', $warna);
}

// Slug URL (huruf kecil, angka, dan tanda hubung)
function validasiSlug(string $slug): bool
{
    return (bool) preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $slug);
}

Ekstraksi Data #

<?php
// Ekstrak semua email dari teks
function ekstrakEmail(string $teks): array
{
    preg_match_all('/[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/', $teks, $m);
    return array_unique($m[0]);
}

// Ekstrak semua URL dari teks
function ekstrakUrl(string $teks): array
{
    preg_match_all('/https?:\/\/[^\s<>"\']+/', $teks, $m);
    return array_unique($m[0]);
}

// Ekstrak hashtag dari teks media sosial
function ekstrakHashtag(string $teks): array
{
    preg_match_all('/#(\w+)/', $teks, $m);
    return $m[1]; // hanya kata setelah #, bukan # itu sendiri
}

// Ekstrak semua angka dari teks
function ekstrakAngka(string $teks): array
{
    preg_match_all('/\d+(?:[.,]\d+)?/', $teks, $m);
    return $m[0];
}

// Ekstrak komponen tanggal
function parseTanggal(string $teks): ?array
{
    if (!preg_match('/(?P<hari>\d{1,2})[\/\-.](?P<bulan>\d{1,2})[\/\-.](?P<tahun>\d{4})/', $teks, $m)) {
        return null;
    }
    return ['hari' => $m['hari'], 'bulan' => $m['bulan'], 'tahun' => $m['tahun']];
}

Transformasi Teks #

<?php
// camelCase ke snake_case
function camelToSnake(string $input): string
{
    $pola   = '/(?<!^)(?=[A-Z])/';
    $snake  = preg_replace($pola, '_', $input);
    return strtolower($snake);
}
echo camelToSnake('camelCaseString'); // camel_case_string
echo camelToSnake('getUserById');     // get_user_by_id

// snake_case ke camelCase
function snakeToCamel(string $input): string
{
    return lcfirst(preg_replace_callback('/_([a-z])/', fn($m) => strtoupper($m[1]), $input));
}
echo snakeToCamel('snake_case_string'); // snakeCaseString

// Bersihkan whitespace berlebih
function bersihkanSpasi(string $input): string
{
    return trim(preg_replace('/\s+/', ' ', $input));
}
echo bersihkanSpasi("  ada   spasi   berlebih  "); // "ada spasi berlebih"

// Highlight kata kunci dalam teks
function highlight(string $teks, string $kataKunci): string
{
    $pola   = '/(' . preg_quote($kataKunci, '/') . ')/i';
    return preg_replace($pola, '<mark>$1</mark>', $teks);
}
echo highlight('Belajar PHP itu menyenangkan', 'php');
// 'Belajar <mark>PHP</mark> itu menyenangkan'

// Sanitasi input: hapus karakter selain huruf, angka, spasi
function sanitasi(string $input): string
{
    return preg_replace('/[^a-zA-Z0-9\s]/', '', $input);
}

preg_quote() — Escape Input User #

Ketika pola regex mengandung data dari user input, selalu escape terlebih dahulu dengan preg_quote():

<?php
$cariKata = $_GET['q'] ?? '';

// ANTI-PATTERN: langsung pakai input user dalam pola — sangat berbahaya!
// Jika user input "a(b", pola menjadi /a(b/ yang invalid → error!
preg_match("/$cariKata/i", $teks);

// BENAR: escape dulu dengan preg_quote()
$escaped   = preg_quote($cariKata, '/'); // argumen kedua = delimiter
$hasilCari = preg_match("/$escaped/i", $teks);

// Untuk highlight hasil pencarian
function cariDanHighlight(string $teks, string $kata): string
{
    if (empty($kata)) return htmlspecialchars($teks);

    $escaped = preg_quote($kata, '~');
    return preg_replace_callback(
        "~($escaped)~i",
        fn($m) => '<mark>' . htmlspecialchars($m[1]) . '</mark>',
        htmlspecialchars($teks)
    );
}

Kapan Regex dan Kapan Tidak #

Gunakan Regex jika:
  ✓ Pola kompleks yang melibatkan variasi atau opsional
  ✓ Parsing teks dengan struktur semi-teratur
  ✓ Validasi format yang lebih dari sekadar keberadaan substring
  ✓ Ekstraksi bagian spesifik dari string dengan capturing group

Hindari Regex jika:
  ✗ Pencarian substring sederhana — gunakan str_contains(), strpos()
  ✗ Cek awalan/akhiran — gunakan str_starts_with(), str_ends_with()
  ✗ Parsing HTML/XML — gunakan DOMDocument atau SimpleXML
  ✗ Parsing JSON — gunakan json_decode()
  ✗ Parsing CSV — gunakan str_getcsv() atau fgetcsv()
<?php
// ANTI-PATTERN: regex untuk operasi string sederhana
if (preg_match('/^hello/', $str)) { }      // berlebihan
if (preg_match('/world$/', $str)) { }      // berlebihan
if (preg_match('/foo/', $str)) { }         // berlebihan

// BENAR: fungsi string bawaan lebih efisien
if (str_starts_with($str, 'hello')) { }   // PHP 8.0+
if (str_ends_with($str, 'world')) { }     // PHP 8.0+
if (str_contains($str, 'foo')) { }        // PHP 8.0+

Ringkasan #

  • Delimiter regex PHP bisa berupa /, #, ~, atau karakter lain — pilih yang tidak muncul dalam pola agar tidak perlu escape berulang.
  • Character class [abc] cocok dengan satu karakter dari set; [^abc] kebalikannya. Shorthand: \d (digit), \w (word char), \s (whitespace), \b (word boundary).
  • Greedy vs lazy quantifier.* cocok sebanyak mungkin; .*? cocok sesedikit mungkin. Lazy hampir selalu lebih tepat untuk parsing HTML-like.
  • Named group (?P<nama>pola) membuat hasil lebih mudah dibaca dari $m[1], $m[2]. Gunakan ${nama} atau \k<nama> dalam replacement.
  • Lookahead/lookbehind mencocokkan posisi berdasarkan konteks tanpa mengonsumsi karakter — sangat berguna untuk validasi password dan ekstraksi data yang bergantung lingkungannya.
  • preg_replace_callback() untuk replacement yang butuh logika PHP (format angka, konversi case, dll.) — lebih kuat dari preg_replace() dengan backreference saja.
  • preg_quote() wajib digunakan sebelum menyisipkan input user ke dalam pola regex — tanpanya, karakter seperti (, ., * bisa membuat pola invalid atau memungkinkan ReDoS attack.
  • Untuk parsing HTML, XML, JSON, CSV — jangan gunakan regex; gunakan parser yang tepat (DOMDocument, json_decode, str_getcsv). Regex tidak bisa mem-parse bahasa rekursif dengan andal.

← Sebelumnya: Date & Time   Berikutnya: Vendoring →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact