Regex di Python
Kenalan dengan regular expression: pola sakti untuk mencari, mengekstrak, dan membersihkan teks kotor dalam data.
Analogi singkat: stensil pencari kata
Bayangkan kamu punya stensil (mal) berlubang bentuk pola tertentu. Tempelkan ke halaman teks mana pun, dan semua kata yang lolos lewat lubangnya langsung ketahuan. Regex (regular expression) adalah stensil digital: kamu mendeskripsikan pola teks yang dicari ("angka 10-13 digit", "format email", "huruf berlebih"), dan Python menemukan semuanya sekaligus, tidak peduli teksnya sepanjang apa.
Kenapa konsep ini ada?
Data teks di dunia nyata itu kotor: nomor HP ditulis "0812-3456-7890" atau "0812 3456 7890" atau "+6281234567890", email kadang typo, komentar penuh simbol aneh. Membersihkannya dengan replace() satu per satu tidak akan selesai. Regex memberi satu bahasa pola yang ringkas untuk menangani semua variasi itu dalam satu operasi.
Empat fungsi utama modul re
import re
teks = "Hubungi 0812-3456-7890 atau email ke [email protected] ya"
# search: cari pola di MANA SAJA dalam teks
m = re.search(r"\d{4}-\d{4}-\d{4}", teks)
print(m.group()) # 0812-3456-7890
# match: cocokkan di AWAL teks saja
print(re.match(r"Hubungi", teks).group()) # Hubungi
print(re.match(r"email", teks)) # None (bukan di awal)
# findall: ambil SEMUA yang cocok sebagai list
print(re.findall(r"\d+", teks)) # ['0812', '3456', '7890']
# sub: ganti semua yang cocok
bersih = re.sub(r"\d", "X", teks)
print(bersih) # Hubungi XXXX-XXXX-XXXX atau email ke [email protected] yaCatatan teknis: Selalu tulis pola regex sebagai raw string (
r"pola"). Tanpa prefixr, backslash seperti\dbisa ditafsirkan Python sebagai escape string biasa sebelum sampai ke regex, sumber bug yang membingungkan.
Pola-pola yang paling sering dipakai
import re
# \d digit, \w huruf/angka/underscore, \s spasi
# + berarti "satu atau lebih", * berarti "nol atau lebih"
# [abc] salah satu dari a/b/c, . karakter apa pun
teks = "Email: [email protected], Budi <[email protected]>"
# pola email sederhana
email = re.findall(r"[\w.]+@[\w.]+", teks)
print(email) # ['[email protected]', '[email protected]']
# pola nomor HP Indonesia yang fleksibel
hp = "Telp 081234567890 atau +62 812-3456-7890"
nomor = re.findall(r"(?:\+62|0)8\d[\d\s-]*", hp)
print(nomor) # ['081234567890', '+62 812-3456-7890']
# normalisasi spasi berlebih
berantakan = "kopi susu gula"
rapi = re.sub(r"\s+", " ", berantakan)
print(rapi) # kopi susu gulaContoh 1: ekstrak angka dari teks campur
import re
# data mentah: harga tertulis campur teks
baris = [
"Kopi susu Rp15.000",
"Roti bakar Rp12.500",
"Teh manis Rp8.000",
]
for b in baris:
# ambil semua digit lalu gabung
angka = re.findall(r"\d+", b)
harga = int("".join(angka))
print(b, "->", harga)
# Kopi susu Rp15.000 -> 15000
# Roti bakar Rp12.500 -> 12500
# Teh manis Rp8.000 -> 8000Contoh 2: bersihkan teks komentar
import re
def bersihkan(teks):
teks = teks.lower() # kecilkan semua
teks = re.sub(r"http\S+", "", teks) # buang URL
teks = re.sub(r"[^a-z0-9\s]", "", teks) # buang simbol, sisakan huruf/angka/spasi
teks = re.sub(r"\s+", " ", teks) # rapikan spasi
return teks.strip()
print(bersihkan("KOPINYA ENAK!!! Beli di sini: https://toko.id/abc"))
# kopinya enak beli di siniFungsi empat baris ini adalah fondasi preprocessing teks sebelum analisis sentimen atau pencarian kata kunci.
Kesalahan umum
SALAH: lupa raw string
re.search("\d+", "abc123") # bisa jalan, tapi rawan salah tafsirBENAR: selalu pakai r"..."
re.search(r"\d+", "abc123") # jelas dan amanSALAH: pakai match untuk mencari di tengah teks
re.match(r"\d+", "kode: 123") # None! match hanya cek awal teksBENAR: pakai search kalau posisi tidak pasti
re.search(r"\d+", "kode: 123").group() # '123'SALAH: pola terlalu rakus menelan semuanya
re.findall(r"<.*>", "<b>tebal</b> dan <i>miring</i>")
# ['<b>tebal</b> dan <i>miring</i>'] -> satu hasil raksasa!BENAR: pakai versi malas (non-greedy) dengan ?
re.findall(r"<.*?>", "<b>tebal</b> dan <i>miring</i>")
# ['<b>', '</b>', '<i>', '</i>']Tantangan
Validasi Email Sederhana
Diberi list string campuran email valid dan tidak. Pakai re.match dengan pola email sederhana untuk memisahkan mana yang valid, lalu cetak keduanya.