Python

Regular Expressions (Regex) Python: Panduan Lengkap

Tutorial lengkap Regular Expressions di Python β€” pola dasar, groups, quantifiers, lookaheads, modul re, dan contoh praktis untuk validasi dan pencarian teks

1. Pengenalan Regular Expressions

Regular Expressions (disingkat Regex atau Regexp) adalah sekumpulan karakter spesial yang membentuk pola pencarian (search pattern). Regex digunakan untuk mencocokkan, mencari, dan memanipulasi string berdasarkan pola tertentu.

Regex adalah salah satu tools paling powerful dalam pemrograman. Dengan regex, Anda bisa melakukan validasi email, nomor telepon, URL, ekstraksi data dari teks, dan banyak lagi β€” semuanya dalam satu baris pola.

Mengapa Belajar Regex?

Kegunaan Contoh
Validasi InputEmail, nomor telepon, password, NIK
Pencarian TeksMencari kata kunci dalam dokumen besar
Ekstraksi DataMengambil angka dari string, parsing log
Replace/SubstitusiMengganti pola tertentu dalam teks
TokenisasiMemecah teks berdasarkan pola tertentu
Web ScrapingMengambil data dari halaman web

Cara Kerja Regex

Diagram: Cara Kerja Regex Engine
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 CARA KERJA REGEX                        β”‚
β”‚                                                         β”‚
β”‚  Input String:  "Halo, email saya: budi@mail.com"      β”‚
β”‚  Regex Pattern: [\w.-]+@[\w.-]+\.\w+                   β”‚
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”‚
β”‚  β”‚  Regex Engine │─────▢│  Match Result    β”‚            β”‚
β”‚  β”‚  Mencocokkan  β”‚      β”‚  budi@mail.com   β”‚            β”‚
β”‚  β”‚  pola per     β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚
β”‚  β”‚  karakter     β”‚                                      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                       β”‚
β”‚                                                         β”‚
β”‚  Langkah:                                               β”‚
β”‚  1. Engine mulai dari karakter pertama                   β”‚
β”‚  2. Mencoba mencocokkan pola karakter per karakter      β”‚
β”‚  3. Jika cocok β†’ kembalikan match                       β”‚
β”‚  4. Jika gagal β†’ geser ke karakter berikutnya           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Modul re di Python

Python menyediakan modul re bawaan untuk bekerja dengan Regular Expressions. Tidak perlu instalasi tambahan β€” langsung bisa digunakan.

Fungsi Utama Modul re

Python β€” re Module
import re

# ========================================
# re.search() β€” Cari pola pertama yang cocok
# ========================================
teks = "Hubungi kami di info@beebane.com atau support@beebane.com"
hasil = re.search(r'[\w.-]+@[\w.-]+\.\w+', teks)
print(hasil.group())  # info@beebane.com (hanya yang pertama)

# ========================================
# re.findall() β€” Temukan semua kecocokan
# ========================================
semua_email = re.findall(r'[\w.-]+@[\w.-]+\.\w+', teks)
print(semua_email)
# ['info@beebane.com', 'support@beebane.com']

# ========================================
# re.match() β€” Cocokkan dari awal string saja
# ========================================
print(re.match(r'Halo', 'Halo dunia'))   # Match
print(re.match(r'dunia', 'Halo dunia'))  # None (bukan di awal)

# ========================================
# re.fullmatch() β€” Cocokkan seluruh string
# ========================================
print(re.fullmatch(r'\d+', '12345'))  # Match
print(re.fullmatch(r'\d+', '123abc')) # None

# ========================================
# re.sub() β€” Ganti pola dalam string
# ========================================
teks = "Nomor HP: 0812-3456-7890"
bersih = re.sub(r'[\-\s]', '', teks)
print(bersih)  # Nomor HP: 081234567890

# Ganti dengan fungsi
def ganti_angka(match):
    return str(int(match.group()) * 2)

hasil = re.sub(r'\d+', ganti_angka, "Angka: 10 20 30")
print(hasil)  # Angka: 20 40 60

# ========================================
# re.split() β€” Pisahkan string berdasarkan pola
# ========================================
teks = "apel; jeruk, mangga: pisang"
kata = re.split(r'[;,\s:]+', teks)
print(kata)  # ['apel', 'jeruk', 'mangga', 'pisang']

# ========================================
# re.compile() β€” Compile pola untuk digunakan berulang
# ========================================
pola_email = re.compile(r'[\w.-]+@[\w.-]+\.\w+')

# Gunakan pola yang sudah di-compile
print(pola_email.search("Email: test@mail.com"))
print(pola_email.findall("a@b.com dan c@d.com"))
πŸ’‘ Tips: Raw String

Selalu gunakan raw string (r'...') saat menulis regex di Python. Raw string mencegah Python menginterpretasi backslash (\) sebagai escape sequence. Misalnya, r'\n' adalah dua karakter \ dan n, bukan newline.

Perbandingan Fungsi re

Fungsi Kegunaan Return Value
re.search()Cari kecocokan pertama di mana sajaMatch object / None
re.match()Cocokkan hanya di awal stringMatch object / None
re.fullmatch()Cocokkan seluruh stringMatch object / None
re.findall()Temukan semua kecocokanList of strings
re.finditer()Seperti findall, tapi iteratorIterator Match objects
re.sub()Ganti kecocokan dengan teks baruString baru
re.split()Pisahkan string berdasarkan polaList of strings
re.compile()Compile pola untuk penggunaan ulangPattern object

3. Karakter dan Pola Dasar

Setiap karakter dalam regex memiliki arti khusus. Memahami karakter dasar adalah fondasi untuk menguasai regex.

Meta Karakter Dasar

Karakter Deskripsi Contoh
.Apapun kecuali newlinea.c cocok "abc", "a1c", "a@c"
^Awal string^Hello cocok "Hello dunia"
$Akhir stringdunia$ cocok "Halo dunia"
\Escape karakter spesial\. cocok titik literal
|Atau (alternation)kucing|anjing
[]Character class[aeiou] cocok huruf vokal
()Grouping(abc)+ cocok "abc", "abcabc"

Special Sequences

Python β€” Special Sequences
import re

# Special sequences β€” shorthand untuk pola umum
# \d  = digit [0-9]
# \D  = bukan digit [^0-9]
# \w  = word character [a-zA-Z0-9_]
# \W  = bukan word character
# \s  = whitespace [ \t\n\r\f\v]
# \S  = bukan whitespace
# \b  = word boundary
# \B  = bukan word boundary

teks = "Order #12345 seharga Rp 75.000 tanggal 25/06/2026"

# Ambil semua angka
angka = re.findall(r'\d+', teks)
print(angka)  # ['12345', '75', '000', '25', '06', '2026']

# Ambil kata-kata saja (tanpa simbol)
kata = re.findall(r'\w+', teks)
print(kata)  # ['Order', '12345', 'seharga', 'Rp', '75', '000', ...]

# Word boundary β€” mencocokkan kata utuh
teks = "cat concatenate category"
print(re.findall(r'\bcat\b', teks))   # ['cat'] (hanya 'cat' utuh)
print(re.findall(r'\bcat', teks))     # ['cat', 'cat', 'cat'] (awal kata)

# Contoh: Pisahkan huruf dan angka
kode = "AB12CD34EF"
hasil = re.findall(r'[A-Z]+|\d+', kode)
print(hasil)  # ['AB', '12', 'CD', '34', 'EF']

# Contoh: Deteksi whitespace berlebih
teks = "Halo    dunia   Python"
bersih = re.sub(r'\s+', ' ', teks)
print(bersih)  # "Halo dunia Python"

Escape Karakter Spesial

Karakter Regex untuk Match Penjelasan
.\.Titik literal
*\*Bintang literal
+\+Plus literal
?\?Tanda tanya literal
[]\[ \]Kurung siku literal
()\( \)Kurung biasa literal
{}\{ \}Kurung kurawal literal
\\\Backslash literal

4. Quantifiers (Pengulangan)

Quantifiers menentukan berapa kali sebuah karakter atau grup harus muncul agar pola cocok.

Quantifier Dasar

Quantifier Arti Contoh
*0 atau lebihab*c cocok "ac", "abc", "abbc"
+1 atau lebihab+c cocok "abc", "abbc" (bukan "ac")
?0 atau 1colou?r cocok "color" dan "colour"
{n}Tepat n kalia{3} cocok "aaa"
{n,}n atau lebiha{2,} cocok "aa", "aaa", "aaaa"
{n,m}Antara n dan m kalia{2,4} cocok "aa", "aaa", "aaaa"

Greedy vs Non-Greedy (Lazy)

Python β€” Greedy vs Lazy
import re

# GREEDY (default) β€” mencocokkan sebanyak mungkin
teks = "<p>Paragraf pertama</p><p>Paragraf kedua</p>"

greedy = re.findall(r'<p>.*</p>', teks)
print(greedy)
# ['<p>Paragraf pertama</p><p>Paragraf kedua</p>']
# Mengambil SEMUA sampai </p> terakhir!

# NON-GREEDY (lazy) β€” tambahkan ? untuk mencocokkan sesedikit mungkin
lazy = re.findall(r'<p>.*?</p>', teks)
print(lazy)
# ['<p>Paragraf pertama</p>', '<p>Paragraf kedua</p>']
# Mengambil masing-masing tag!

# Contoh lain β€” ekstraksi konten dalam tanda kutip
teks = 'nama="Budi" umur="25" kota="Jakarta"'

greedy_match = re.search(r'".*"', teks)
print(greedy_match.group())   # "Budi" umur="25" kota="Jakarta"

lazy_match = re.search(r'".*?"', teks)
print(lazy_match.group())     # "Budi"

# Semua quantifier bisa dijadikan lazy dengan menambah ?
# *?  = 0 atau lebih (sesedikit mungkin)
# +?  = 1 atau lebih (sesedikit mungkin)
# ??  = 0 atau 1 (sesedikit mungkin)
# {n,m}? = antara n dan m (sesedikit mungkin)
⚠️ Peringatan

Kesalahan paling umum dalam regex adalah menggunakan greedy quantifier (.*) saat ingin mencocokkan bagian tertentu dari teks. Gunakan lazy (.*?) untuk menghindari match yang terlalu panjang. Terutama saat mem-parsing HTML atau XML.

5. Character Classes

Character classes memungkinkan Anda mendefinisikan himpunan karakter yang ingin dicocokkan.

Custom Character Classes dengan Bracket Notation

Python β€” Character Classes
import re

# Character classes dengan []
# [abc]     = cocok 'a', 'b', atau 'c'
# [^abc]    = cocok apapun KECUALI 'a', 'b', 'c'
# [a-z]     = cocok huruf kecil a sampai z
# [A-Z]     = cocok huruf besar A sampai Z
# [0-9]     = cocok digit 0 sampai 9
# [a-zA-Z]  = cocok semua huruf

# Contoh: Cocokkan huruf vokal
teks = "Hello World"
vokal = re.findall(r'[aeiouAEIOU]', teks)
print(vokal)  # ['e', 'o', 'o']

# Range dan kombinasi
# Cocokkan angka heksadesimal
hex_pattern = r'[0-9a-fA-F]+'
print(re.findall(hex_pattern, "Warna: #FF5733 dan #00AA99"))
# ['FF5733', '00AA99']

# Negasi dengan ^
# Cocokkan apapun kecuali huruf dan angka
teks = "Halo, Dunia! Apa kabar?"
non_alnum = re.findall(r'[^a-zA-Z0-9]', teks)
print(non_alnum)  # [',', ' ', '!', ' ', ' ', '?']

# Character class dengan special sequences
# [\w.-] = word char, titik, atau dash
# Cocok untuk bagian username dalam email
pola = r'[\w.-]+@[\w.-]+\.\w+'
email = "kontak@beebane-labs.id"
print(re.search(pola, email).group())  # kontak@beebane-labs.id

# Hati-hati: di dalam [], . adalah literal (bukan wildcard)
print(re.findall(r'[.]', "a.b.c"))  # ['.', '.']

# Karakter ] harus di-escape di dalam class
print(re.findall(r'[\[\]]', "Halo [dunia]"))
# ['[', ']']

Unicode dalam Character Classes

Python β€” Unicode Regex
import re

# Flag re.UNICODE (aktif secara default di Python 3)
# \w dengan flag UNICODE mencocokkan huruf internasional

teks = "Nama: Budi MΓΌller dan JosΓ© GarcΓ­a"

# Cari semua kata (termasuk karakter Unicode)
kata = re.findall(r'\w+', teks, re.UNICODE)
print(kata)  # ['Nama', 'Budi', 'MΓΌller', 'dan', 'JosΓ©', 'GarcΓ­a']

# Cek apakah string hanya huruf (termasuk Unicode)
pola = r'^[a-zA-ZΓ€-ΓΏ]+$'
print(re.match(pola, "Crème"))  # Match (huruf Prancis)
print(re.match(pola, "HΓ©llo"))  # Match
print(re.match(pola, "HΓ©llo123"))  # None (ada angka)

6. Groups dan Capturing

Groups memungkinkan Anda menangkap (capture) bagian spesifik dari match dan menggunakannya kembali. Ini sangat berguna untuk parsing dan ekstraksi data.

Capturing Groups

Python β€” Groups
import re

# Basic capturing group dengan ()
teks = "Tanggal: 25-06-2026"
match = re.search(r'(\d{2})-(\d{2})-(\d{4})', teks)

if match:
    print(match.group())    # 25-06-2026 (seluruh match)
    print(match.group(0))   # 25-06-2026 (sama dengan di atas)
    print(match.group(1))   # 25 (grup 1: hari)
    print(match.group(2))   # 06 (grup 2: bulan)
    print(match.group(3))   # 2026 (grup 3: tahun)
    print(match.groups())   # ('25', '06', '2026') (semua grup)

# Contoh: Parsing URL
url = "https://www.beebane.com/articles/python?id=42"
match = re.search(r'(https?)://([^/]+)(/[^\?]*)(?:\?(.+))?', url)
if match:
    protokol = match.group(1)  # https
    domain = match.group(2)    # www.beebane.com
    path = match.group(3)      # /articles/python
    query = match.group(4)     # id=42
    print(f"Protokol: {protokol}")
    print(f"Domain: {domain}")
    print(f"Path: {path}")
    print(f"Query: {query}")

# Non-capturing group dengan (?:)
# Group yang tidak menangkap, hanya untuk grouping
teks = "25/06/2026 dan 01/01/2025"
matches = re.findall(r'(?:\d{2}/){2}\d{4}', teks)
print(matches)  # ['25/06/2026', '01/01/2025']

Named Groups

Python β€” Named Groups
import re

# Named groups dengan (?P<name>...)
teks = "Nama: Budi Santoso, Umur: 25, Kota: Jakarta"
match = re.search(
    r'Nama: (?P<nama>[\w\s]+), Umur: (?P<umur>\d+), Kota: (?P<kota>\w+)',
    teks
)

if match:
    print(match.group('nama'))  # Budi Santoso
    print(match.group('umur'))  # 25
    print(match.group('kota'))  # Jakarta

    # Akses sebagai dictionary
    print(match.groupdict())
    # {'nama': 'Budi Santoso', 'umur': '25', 'kota': 'Jakarta'}

# Backreference β€” gunakan ulang grup yang sudah ditangkap
# \1, \2, dst untuk mengulang grup berdasarkan posisi
# (?P=name) untuk mengulang grup berdasarkan nama

# Deteksi tag HTML yang cocok (opening dan closing)
teks = "<p>Paragraf</p> dan <div>Divisi</div>"
pola = r'<(\w+)>.*?</\1>'
matches = re.findall(pola, teks)
print(matches)  # ['p', 'div']

# Cek apakah string punya karakter berulang berturut-turut
teks = "hello"  # punya 'll'
if re.search(r'(.)\1', teks):
    print("Ada karakter berulang!")

# Named backreference
teks = "<span>Teks</span>"
pola = r'<(?P<tag>\w+)>.*?</(?P=tag)>'
print(re.search(pola, teks).group())  # <span>Teks</span>

# findall dengan groups β€” return group content, bukan full match
teks = "2026-06-25 dan 2025-12-31"
hasil = re.findall(r'(\d{4})-(\d{2})-(\d{2})', teks)
print(hasil)  # [('2026', '06', '25'), ('2025', '12', '31')]

7. Lookaheads dan Lookbehinds

Lookaheads dan lookbehinds adalah zero-width assertions β€” mereka mencocokkan pola tanpa mengonsumsi karakter. Ini sangat berguna untuk memeriksa konteks tanpa mengubah match.

Jenis Lookaround

Jenis Sintaks Arti
Positive Lookahead(?=...)Diikuti oleh pola
Negative Lookahead(?!...)TIDAK diikuti oleh pola
Positive Lookbehind(?<=...)Didahului oleh pola
Negative Lookbehind(?<!...)TIDAK didahului oleh pola
Python β€” Lookaheads & Lookbehinds
import re

# ========================================
# POSITIVE LOOKAHEAD (?=...)
# Cocokkan sesuatu yang DIIKUTI oleh pola
# ========================================
teks = "100kg 200lbs 300kg 400lbs"

# Ambil angka yang diikuti "kg" (tanpa mengonsumsi "kg")
hasil = re.findall(r'\d+(?=kg)', teks)
print(hasil)  # ['100', '300']

# ========================================
# NEGATIVE LOOKAHEAD (?!...)
# Cocokkan sesuatu yang TIDAK diikuti oleh pola
# ========================================
# Ambil angka yang TIDAK diikuti "kg"
hasil = re.findall(r'\d+(?!kg)', teks)
print(hasil)  # ['200', '400'] (dan juga '10', '30')

# Perbaikan β€” gunakan boundary
hasil = re.findall(r'\b\d+(?!kg)\b', teks)
print(hasil)  # Lebih tepat

# ========================================
# POSITIVE LOOKBEHIND (?<=...)
# Cocokkan sesuatu yang DIDAHului oleh pola
# ========================================
teks = "Harga: Rp150.000 dan Rp200.000"

# Ambil angka setelah "Rp"
hasil = re.findall(r'(?<=Rp)\d[\d.]+', teks)
print(hasil)  # ['150.000', '200.000']

# ========================================
# NEGATIVE LOOKBEHIND (?<!...)
# Cocokkan sesuatu yang TIDAK didahului oleh pola
# ========================================
# Ambil angka yang bukan diawali "Rp"
hasil = re.findall(r'(?<!Rp)\b\d+\b', "Rp100 ada 200 Rp300")
print(hasil)  # ['200']

# ========================================
# Contoh Gabungan: Validasi password
# Password harus:
# - Minimal 8 karakter
# - Ada huruf besar
# - Ada huruf kecil
# - Ada angka
# ========================================
def validasi_password(pw):
    pola = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$'
    return bool(re.match(pola, pw))

print(validasi_password("MyPass123"))   # True
print(validasi_password("mypass123"))   # False (tidak ada huruf besar)
print(validasi_password("MYPASS123"))   # False (tidak ada huruf kecil)
print(validasi_password("MyPass"))      # False (tidak ada angka)

# ========================================
# Contoh: Pisahkan kata yang diikuti angka
# ========================================
teks = "Bab 1, Bab 2, Bab 3, Pendahuluan, Bab 4"
hasil = re.findall(r'\w+(?=\s\d)', teks)
print(hasil)  # ['Bab', 'Bab', 'Bab', 'Bab']
Diagram: Lookaround Visualization
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            POSITIVE LOOKAHEAD (?=...)                β”‚
β”‚                                                     β”‚
β”‚  Input: "100kg 200lbs"                              β”‚
β”‚  Pattern: \d+(?=kg)                                 β”‚
β”‚                                                     β”‚
β”‚  100  ← match! β†’  [kg] ← diperiksa tapi            β”‚
β”‚                    ^^^    tidak dikonsumsi           β”‚
β”‚                                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚            POSITIVE LOOKBEHIND (?<=...)              β”‚
β”‚                                                     β”‚
β”‚  Input: "Rp150.000"                                 β”‚
β”‚  Pattern: (?<=Rp)\d+                               β”‚
β”‚                                                     β”‚
β”‚  [Rp]  ← diperiksa tapi β†’  150.000 ← match!        β”‚
β”‚  ^^^      tidak dikonsumsi                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

8. Flags dan Modifiers

Flags mengubah cara regex engine memproses pola. Di Python, flag diberikan sebagai parameter kedua pada fungsi re, atau inline dalam pola.

Daftar Flags

Flag Singkatan Fungsi
re.IGNORECASEre.ITidak peduli huruf besar/kecil
re.MULTILINEre.M^ dan $ berlaku per baris
re.DOTALLre.S. mencocokkan termasuk newline
re.VERBOSEre.XBoleh pakai komentar dan spasi
re.UNICODEre.UUnicode matching (default Python 3)
re.ASCIIre.AASCII-only matching
Python β€” Flags
import re

# ========================================
# re.IGNORECASE (re.I)
# ========================================
teks = "Python PYTHON python PyThOn"
hasil = re.findall(r'python', teks, re.IGNORECASE)
print(hasil)  # ['Python', 'PYTHON', 'python', 'PyThOn']

# Inline flag: (?i)
hasil = re.findall(r'(?i)python', teks)
print(hasil)  # ['Python', 'PYTHON', 'python', 'PyThOn']

# ========================================
# re.MULTILINE (re.M)
# ========================================
teks = """baris pertama
baris kedua
baris ketiga"""

# Tanpa MULTILINE: ^ hanya cocok di awal string
print(re.findall(r'^baris', teks))  # ['baris']

# Dengan MULTILINE: ^ cocok di awal setiap baris
print(re.findall(r'^baris', teks, re.MULTILINE))
# ['baris', 'baris', 'baris']

# Inline flag: (?m)
print(re.findall(r'(?m)^baris', teks))
# ['baris', 'baris', 'baris']

# ========================================
# re.DOTALL (re.S)
# ========================================
teks = "<p>Paragraf\npertama</p>"

# Tanpa DOTALL: . tidak cocok newline
print(re.findall(r'<p>(.*)</p>', teks))  # []

# Dengan DOTALL: . mencocokkan semua termasuk newline
print(re.findall(r'<p>(.*)</p>', teks, re.DOTALL))
# ['Paragraf\npertama']

# ========================================
# re.VERBOSE (re.X) β€” untuk regex kompleks
# ========================================
# Boleh pakai komentar dan spasi untuk readability

pola_email = re.compile(r"""
    ^                   # Awal string
    [\w.-]+             # Username (word chars, titik, dash)
    @                   # Simbol @
    [\w.-]+             # Domain name
    \.                  # Titik (escape)
    \w{2,}              # TLD minimal 2 karakter
    $                   # Akhir string
""", re.VERBOSE)

print(pola_email.match("user@domain.com"))  # Match
print(pola_email.match("invalid-email"))     # None

# Menggabungkan beberapa flags dengan operator |
pola = re.compile(r'^python', re.MULTILINE | re.IGNORECASE)
teks = "Python\nJAVA\nPYTHON\nrust"
print(pola.findall(teks))  # ['Python', 'PYTHON']

9. Contoh Praktis Regex

Berikut adalah kumpulan contoh nyata penggunaan regex dalam kehidupan sehari-hari programmer.

Validasi Berbagai Format

Python β€” Contoh Praktis
import re

# ========================================
# 1. Validasi Email
# ========================================
def validasi_email(email):
    pola = r'^[\w.-]+@[\w.-]+\.\w{2,}$'
    return bool(re.match(pola, email))

print(validasi_email("budi@mail.com"))          # True
print(validasi_email("budi.santoso@co.id"))     # True
print(validasi_email("invalid-email"))           # False
print(validasi_email("budi@"))                   # False

# ========================================
# 2. Validasi Nomor Telepon Indonesia
# ========================================
def validasi_telepon(no_hp):
    # Format: 08xx-xxxx-xxxx atau +628xx-xxxx-xxxx
    pola = r'^(\+62|0)8\d{2}[\s-]?\d{4}[\s-]?\d{3,4}$'
    return bool(re.match(pola, no_hp))

print(validasi_telepon("081234567890"))      # True
print(validasi_telepon("+6281234567890"))    # True
print(validasi_telepon("0812-3456-7890"))    # True
print(validasi_telepon("0812 3456 7890"))    # True
print(validasi_telepon("123456"))            # False

# ========================================
# 3. Ekstraksi Hashtag dari Teks Media Sosial
# ========================================
def ekstrak_hashtag(teks):
    return re.findall(r'#(\w+)', teks)

post = "Belajar #Python dan #Regex di #BeebaneLabs, seru! #BelajarKoding"
print(ekstrak_hashtag(post))
# ['Python', 'Regex', 'BeebaneLabs', 'BelajarKoding']

# ========================================
# 4. Validasi Password Kuat
# ========================================
def validasi_password(pw):
    if len(pw) < 8:
        return False, "Minimal 8 karakter"
    if not re.search(r'[A-Z]', pw):
        return False, "Harus ada huruf besar"
    if not re.search(r'[a-z]', pw):
        return False, "Harus ada huruf kecil"
    if not re.search(r'\d', pw):
        return False, "Harus ada angka"
    if not re.search(r'[!@#$%^&*(),.?":{}|<>]', pw):
        return False, "Harus ada simbol"
    return True, "Password kuat!"

print(validasi_password("MyP@ss123"))   # (True, 'Password kuat!')
print(validasi_password("mypassword"))  # (False, 'Harus ada huruf besar')

# ========================================
# 5. Parsing File CSV Sederhana
# ========================================
def parse_csv_line(line):
    # Pisahkan berdasarkan koma, handle kutip
    return re.findall(r'(?:[^,"]|"[^"]*")+', line)

baris = 'Budi,"Jakarta, Indonesia",25,"Programmer, AI"'
print(parse_csv_line(baris))
# ['Budi', '"Jakarta, Indonesia"', '25', '"Programmer, AI"']

# ========================================
# 6. Masking Nomor Kartu Kredit
# ========================================
def mask_kartu(no_kartu):
    # Tampilkan hanya 4 digit terakhir
    return re.sub(r'\d(?=\d{4})', '*', no_kartu)

print(mask_kartu("1234567890123456"))  # ************3456
print(mask_kartu("4111-1111-1111-1111"))  # ****-****-****-1111

Regex untuk Web Scraping

Python β€” Web Scraping Regex
import re

# Contoh parsing HTML sederhana dengan regex
html = """
<div class="product">
  <h2>Laptop ASUS</h2>
  <span class="price">Rp 12.500.000</span>
</div>
<div class="product">
  <h2>Keyboard Mechanical</h2>
  <span class="price">Rp 850.000</span>
</div>
"""

# Ekstrak nama produk
produk = re.findall(r'<h2>(.*?)</h2>', html)
print(produk)  # ['Laptop ASUS', 'Keyboard Mechanical']

# Ekstrak harga
harga = re.findall(r'<span class="price">(.*?)</span>', html)
print(harga)  # ['Rp 12.500.000', 'Rp 850.000']

# Ekstrak semua link dari HTML
html_links = '<a href="https://example.com">Link 1</a> <a href="/page">Link 2</a>'
links = re.findall(r'href=["\']([^"\']+)["\']', html_links)
print(links)  # ['https://example.com', '/page']

# Parsing log Apache/Nginx
log = '192.168.1.1 - - [25/Jun/2026:10:30:00 +0700] "GET /index.html HTTP/1.1" 200 1234'
pola = r'(\S+) \S+ \S+ \[([^\]]+)\] "(\w+) (\S+) \S+" (\d+) (\d+)'
match = re.search(pola, log)
if match:
    print(f"IP: {match.group(1)}")       # 192.168.1.1
    print(f"Waktu: {match.group(2)}")    # 25/Jun/2026:10:30:00 +0700
    print(f"Method: {match.group(3)}")   # GET
    print(f"Path: {match.group(4)}")     # /index.html
    print(f"Status: {match.group(5)}")   # 200
    print(f"Size: {match.group(6)}")     # 1234
πŸ’‘ Tips: Kapan TIDAK Menggunakan Regex

Regex sangat kuat, tapi bukan solusi untuk semua masalah teks. Hindari regex untuk: (1) Parsing HTML/XML yang kompleks β€” gunakan library seperti BeautifulSoup atau lxml. (2) Validasi struktur data yang rumit β€” gunakan parser dedicated. (3) Pola yang sangat kompleks dan sulit dipahami β€” pertimbangkan alternatif. Ingat: "Some people, when confronted with a problem, think 'I know, I'll use regular expressions.' Now they have two problems."

10. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Regular Expressions Python:

Pertanyaan 1: Apa perbedaan antara re.search() dan re.match()?

a) Tidak ada perbedaan, fungsinya sama
b) search() mencari di seluruh string, match() hanya di awal string
c) match() lebih cepat dari search()
d) search() mengembalikan list, match() mengembalikan string

Pertanyaan 2: Apa output dari kode berikut? re.findall(r'\d+', "12 abc 345 def 6")

a) ['12', 'abc', '345', 'def', '6']
b) ['12', '345', '6']
c) '123456'
d) ['1', '2', '3', '4', '5', '6']

Pertanyaan 3: Apa arti dari .*? dalam regex?

a) Mencocokkan 0 atau lebih karakter (greedy)
b) Mencocokkan tepat 1 karakter
c) Mencocokkan 0 atau lebih karakter (non-greedy/lazy)
d) Mencocokkan 1 atau lebih karakter (lazy)

Pertanyaan 4: Bagaimana cara menggunakan named group dalam regex Python?

a) (name:pattern)
b) (?P<name>pattern)
c) (<name>pattern)
d) (?name=pattern)

Pertanyaan 5: Apa fungsi dari positive lookahead (?=...) dalam regex?

a) Mencocokkan pola dan mengonsumsi karakter setelahnya
b) Mencocokkan pola yang DIDAHului oleh pola tertentu
c) Mencocokkan pola yang DIIKUTI oleh pola tertentu tanpa mengonsumsi karakter
d) Menghapus semua kecocokan dari string
πŸ” Zoom
100%
🎨 Tema