Regex Across Languages — Regex

Regex di Bahasa Lain (PHP, Python, Go) Sejauh ini kita belajar regex dari sudut pandang JavaScript. Tapi setiap bahasa punya flavor regex yang sedikit berbeda…

Regex di Bahasa Lain (PHP, Python, Go)

Sejauh ini kita belajar regex dari sudut pandang JavaScript. Tapi setiap bahasa punya flavor regex yang sedikit berbeda — flag-nya beda, syntax delimiter beda, dan fitur lanjutan kadang tidak tersedia. Mari bedah perbedaannya.

Flavor Regex

Flavor Dipakai di Catatan
ECMAScript JavaScript Default di browser + Node
PCRE PHP, Perl, kebanyakan bahasa Paling lengkap fitur
POSIX BRE/ERE grep, sed tradisional Lebih terbatas
RE2 Go regexp, Google Linear time, tidak ada backreferences/lookbehind

PHP: preg_* Functions

PHP pakai PCRE dengan delimiter di sekeliling pattern:

// Delimiter `/` (paling umum), bisa juga # atau ~
if (preg_match("/^\d{4}-\d{2}-\d{2}$/", "2024-03-15")) {
    echo "Format valid";
}

// preg_match_all: semua match
preg_match_all("/\d+/", "Ada 3 dan 12 ikan", $matches);
// $matches[0] = ["3", "12"]

// preg_replace: substitusi
$hasil = preg_replace("/\s+/", " ", "terlalu    banyak   spasi");
// "terlalu banyak spasi"

// preg_replace_callback: dengan fungsi
$upper = preg_replace_callback("/[a-z]+/", fn($m) => strtoupper($m[0]), "halo dunia");
// "HALO DUNIA"

Flag PHP (setelah delimiter): i (case-insensitive), m (multiline), s (dotall), u (Unicode), x (verbose, boleh whitespace dan komentar).

Python: re Module

Python punya re.match vs re.search — perbedaannya penting:

import re

# re.match: anchored di awal string (seperti regex dengan ^)
re.match(r"hello", "hello world")       # Match
re.match(r"world", "hello world")       # None!

# re.search: cari di mana saja
re.search(r"world", "hello world")      # Match

# re.findall: semua match sebagai list
re.findall(r"\d+", "Ada 3 dan 12 ikan")
# ["3", "12"]

# re.sub: substitusi
re.sub(r"\s+", " ", "terlalu    banyak spasi")

# Compiled regex (lebih cepat kalau dipakai berulang)
pattern = re.compile(r"\d{4}-\d{2}-\d{2}")
pattern.match("2024-03-15")

Flag Python: re.I/re.IGNORECASE, re.M/re.MULTILINE, re.S/re.DOTALL, re.X/re.VERBOSE, re.U/re.UNICODE (default di Python 3).

Go: regexp (RE2)

Go pakai RE2 — dijamin linear time, jadi tidak bisa kena ReDoS. Trade-off: tidak support backreferences \1 dan lookbehind (?<=...).

import "regexp"

re := regexp.MustCompile(`\d+`)
re.MatchString("Ada 3 ikan")           // true
re.FindString("Ada 3 ikan")            // "3"
re.FindAllString("3 dan 12", -1)       // ["3", "12"]
re.ReplaceAllString("3 dan 12", "X")   // "X dan X"

Raw Strings: Hindari Double-Escape Neraka

PHP, JavaScript, dan Python sama-sama butuh escape backslash di string biasa. Solusi:

Bahasa Raw string syntax
Python r"\d+"
Go `\d+`
JavaScript /\d+/ (regex literal) atau String.raw
PHP Single quotes '\d+' (tapi masih perlu \\ untuk backslash literal)

Perbedaan Penting

Fitur JS PHP Python Go (RE2)
Backreferences \1
Lookbehind (?<=...) ✅ (modern)
Named groups (?<name>...) ✅ ((?P<name>...) juga) ✅ ((?P<name>...)) ✅ ((?P<name>...))
Possessive a++
Atomic (?>...) ✅ (3.11+)
Unicode \p{Letter} ✅ (flag u) ✅ (flag u)

grep vs egrep vs grep -P

# Basic regex (BRE): `+`, `?`, `(` harus di-escape
grep "colou\?r" file.txt

# Extended regex (ERE): syntax modern tanpa escape
grep -E "colou?r" file.txt
egrep "colou?r" file.txt   # Sama dengan grep -E

# PCRE mode: full PCRE features
grep -P "\d{4}-\d{2}-\d{2}" file.txt

Tips Berpindah Bahasa

  1. Cek delimiter — PHP butuh /, JS pakai / juga tapi sebagai literal, Python string.
  2. Cek default anchor — Python re.match anchored, kebanyakan yang lain tidak.
  3. Cek flag syntax — konstanta re.I vs character i.
  4. Cek fitur support — kalau pindah ke Go/RE2, pastikan tidak pakai backref/lookbehind.
  5. Test di regex101.com — pilih flavor yang sesuai target bahasa.

🎭 Analogi sehari-hari: Regex flavor = dialect bahasa. Indonesia, Malaysia, Brunei semua "Melayu" tapi beda kata, beda intonasi, beda slang. JavaScript, PHP, Python, Go semua "regex" tapi beda syntax, beda fitur, beda quirk. Kalimat di satu dialect bisa lucu/salah di dialect lain.

💡 RE2 (Go) tradeoff: Linear time guaranteed (no ReDoS!) tapi gak support backreferences (\1) dan lookbehind. Worth it untuk safety. Cloudflare seharusnya pakai RE2 di 2019 — outage gak akan terjadi. Ada trend industri ke RE2 untuk user-facing regex.

⚠️ Jebakan cross-language:

🎯 Quick reference dialect:

TL;DR: Regex flavor (ECMAScript, PCRE, POSIX, RE2) beda fitur + syntax. Pindah bahasa: cek delimiter, default anchor, flag syntax, fitur support. RE2 trade speed untuk linear-time guarantee — pakai untuk user input.

Yang akan kamu pelajari