Dasar-dasar regex

Literal, kelas karakter, dan kuantifier sebagai keterampilan pemulihan teks berantakan.

Daftar isi

Regular expression (regex) adalah notasi untuk menyatakan pola teks, dan Python menyediakan mesin pencocokannya melalui modul re bawaan. Topik ini membahas tiga bahan pembentuk pola, yaitu literal (potongan yang dicocokkan apa adanya), kelas karakter, dan kuantifier, lalu menutupnya dengan tiga fungsi inti untuk mencari, mengumpulkan, dan mengubah kecocokan. Seluruh teknik diterapkan pada satu kasus kerja yang sama, yaitu memulihkan baris catatan sensor suhu yang berantakan menjadi data yang rapi dan siap diolah.

Literal dan kelas karakter#

Pola regex tersusun dari dua jenis bahan. Potongan yang dicocokkan apa adanya disebut literal, contohnya huruf-huruf yang menyusun pola suhu. Selain itu terdapat metacharacter, yaitu karakter dengan makna khusus seperti ., [, *, dan \. Apabila salah satu karakter khusus itu perlu dicari sebagai karakter biasa, tambahkan garis miring terbalik di depannya, sehingga titik pada angka desimal ditulis \. dalam pola.

Kelas karakter (character class) melonggarkan satu posisi kecocokan menjadi sekumpulan karakter yang diperbolehkan. Kelas [A-Z0-9] mencocokkan satu huruf kapital atau satu digit, sedangkan tanda ^ di awal kelas membalik keanggotaannya, sehingga [^0-9] mencocokkan satu karakter apa pun yang bukan digit. Modul re juga menyediakan kelas bawaan yang pendek, yaitu \d untuk digit, \w untuk huruf, angka, dan garis bawah, serta \s untuk spasi. Bentuk negasinya adalah \D, \W, dan \S.

python Contoh: literal dan kelas karakter
import re

teks = "Sensor suhu A7 mencatat 27.5 derajat pada pukul 09.14."

# literal: potongan pola dicocokkan apa adanya
print(re.findall("suhu", teks))

# kelas karakter: satu huruf kapital diikuti satu digit
print(re.findall(r"[A-Z][0-9]", teks))

# kelas bawaan: \d untuk digit, dengan titik literal yang ditulis \.
print(re.findall(r"\d+\.\d", teks))

# rentang huruf kecil dicocokkan di mana pun posisinya
print(re.findall(r"[a-z]+", teks))
text Keluaran
['suhu']
['A7']
['27.5', '09.1']
['ensor', 'suhu', 'mencatat', 'derajat', 'pada', 'pukul']

Keluaran di atas memperlihatkan pembagian kerjanya. Pola "suhu" menemukan satu kata persis, sedangkan kelas [A-Z][0-9] menemukan kode A7 karena dua posisinya masing-masing diatur oleh satu kelas. Pola \d+\.\d menemukan angka desimal dengan titik yang ditulis \., sehingga hanya titik sungguhan yang dianggap kecocokan. Daftar pada baris terakhir memuat ensor karena kelas [a-z]+ mencocokkan rentetan huruf kecil di mana pun posisinya, termasuk di tengah kata Sensor.

Kuantifier: berapa banyak yang dicocokkan#

Kelas karakter menentukan apa yang boleh cocok pada satu posisi, sedangkan kuantifier (quantifier) menentukan berapa kali elemen sebelumnya diulang. Tabel berikut merangkum empat bentuk yang paling sering dipakai.

KuantifierJumlah pengulangan
+satu kali atau lebih
*nol kali atau lebih
?nol kali atau satu kali
{m,n}paling sedikit m kali dan paling banyak n kali

Semua kuantifier di atas bersifat greedy (rakus), yaitu mengambil sebanyak mungkin sebelum menyerahkan sisa teks ke bagian pola berikutnya. Setiap kuantifier juga memiliki versi lazy yang ditulis dengan tambahan tanda tanya, misalnya +?, dan versi ini berhenti pada kecocokan terpendek yang mungkin. Topik ini memakai versi greedy sebagai perilaku bawaan, sehingga kecocokan yang diperoleh biasanya sepanjang mungkin.

python Contoh: tiga kuantifier pada satu baris bacaan
import re

bacaan = "pukul 09.14, 09.15, 09.16, dan 09.17"

# kuantifier + : satu kali atau lebih
print(re.findall(r"09\.\d+", bacaan))

# kuantifier ? : nol atau satu kali; findall mengembalikan isi grup
print(re.findall(r"09\.1(5)?", bacaan))

# kuantifier {m,n} : rentang jumlah pengulangan
print(re.findall(r"\d{2}\.\d{2}", bacaan))
text Keluaran
['09.14', '09.15', '09.16', '09.17']
['', '5', '', '']
['09.14', '09.15', '09.16', '09.17']

Baris pertama keluaran menemukan empat bacaan sekaligus karena + memperpanjang digit sesudah titik sebanyak mungkin. Baris kedua menyimpan kejutan yang lazim dijumpai, yaitu findall yang polanya memuat grup penangkap mengembalikan isi grupnya alih-alih kecocokan utuhnya, sehingga angka 5 pada 09.15 muncul sendirian dan kecocokan tanpa angka tersebut dikembalikan sebagai string kosong. Baris ketiga kembali utuh karena {2} mengulang kelas \d tanpa membentuk grup. Perilaku grup ini ditemui kembali pada pembahasan tiga fungsi inti di bawah.

Tiga fungsi inti modul re#

Fungsi re.search(pola, teks) memeriksa seluruh teks dan mengembalikan objek Match untuk kecocokan pertama, atau None bila tidak ada yang cocok. Objek Match menyimpan potongan yang cocok beserta posisinya melalui group(), start(), dan span(). Fungsi re.findall(pola, teks) mengumpulkan setiap kecocokan ke dalam daftar, sedangkan re.sub(pola, pengganti, teks) mengganti seluruh kecocokan dan mengembalikan teks barunya. Ketiga fungsi juga menerima penanda perilaku sebagai argumen tambahan, contohnya re.IGNORECASE agar huruf besar-kecil diabaikan dan argumen count pada re.sub untuk membatasi jumlah penggantian. Ketiganya menutup kebutuhan mayoritas pekerjaan pembersihan teks sehari-hari.

python Contoh: search, findall, dan sub
import re

catatan = "Budi mencatat suhu 27.5 dan 29.0 pada pagi hari."

# search: kecocokan pertama sebagai objek Match
m = re.search(r"\d+\.\d", catatan)
print(m.group(0), "di posisi", m.start())

# findall: seluruh kecocokan sebagai daftar string
print(re.findall(r"\d+\.\d", catatan))

# sub: penggantian seluruh kecocokan
print(re.sub(r"\d+\.\d", "NN.N", catatan))
text Keluaran
27.5 di posisi 19
['27.5', '29.0']
Budi mencatat suhu NN.N dan NN.N pada pagi hari.

Pola yang sama dipakai tiga kali pada contoh di atas sehingga perbedaannya mudah dibaca. Fungsi search berhenti pada angka pertama dan menunjukkan posisinya, findall mengembalikan dua angka sebagai daftar, sedangkan sub menandai kedua angka sebagai NN.N tanpa menyentuh bagian lain kalimat.

Studi kasus: membersihkan catatan sensor suhu#

Baris pada program berikut adalah catatan sensor suhu persis sebagaimana ditemukan pada berkas log, yaitu spasi berlebih di mana-mana, pasangan kunci=nilai yang menempel pada kepala log, dan komentar yang menggantung di akhir baris. Tiga tahap pembersihan cukup untuk memulihkannya, dan setiap tahap memakai satu bahan yang sudah dibahas di atas.

Program pada berkas bersih_log.py menjalankan ketiga tahap itu. Tahap pertama mengekstrak kepala log berupa tanggal, jam, dan pengenal sensor dengan pola literal, kelas, dan kuantifier. Tahap kedua mengumpulkan pasangan kunci=nilai dengan bantuan + dan \S+. Tahap ketiga membuang komentar setelah tanda pagar, lalu merapatkan rangkaian spasi menjadi satu spasi.

python bersih_log.py
import re

# Satu baris catatan sensor suhu yang berantakan.
log = "2026-11-07 09:14:22   [sensor-03]   suhu=27.5C  kelembapan=68%  status=OK   # bacaan rutin pagi"

print("Baris asli :", log)

# Tahap 1: ekstrak kepala log dengan literal, kelas karakter, dan kuantifier.
m = re.search(r"(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\s+\[(sensor-\d+)\]", log)
print("Tahap 1    :", m.groups())

# Tahap 2: kumpulkan pasangan kunci=nilai dengan bantuan kuantifier +.
print("Tahap 2    :", re.findall(r"(\w+)=(\S+)", log))

# Tahap 3: buang komentar setelah tanda pagar, lalu rapikan spasi berlebih.
tanpa_komentar = re.sub(r"#.*", "", log)
print("Tahap 3    :", re.sub(r"\s+", " ", tanpa_komentar).strip())
text Keluaran
Baris asli : 2026-11-07 09:14:22   [sensor-03]   suhu=27.5C  kelembapan=68%  status=OK   # bacaan rutin pagi
Tahap 1    : ('2026-11-07', '09:14:22', 'sensor-03')
Tahap 2    : [('suhu', '27.5C'), ('kelembapan', '68%'), ('status', 'OK')]
Tahap 3    : 2026-11-07 09:14:22 [sensor-03] suhu=27.5C kelembapan=68% status=OK

Keluaran ketiga tahap menunjukkan pemulihan yang lengkap. Metode groups() mengembalikan tiga potongan kepala log sebagai tuple, findall mengembalikan tiga pasangan yang siap diubah menjadi dictionary, dan baris terakhir adalah teks bersih yang kolom-kolomnya mudah dipisah. Dari titik ini, data sensor siap masuk ke tabel atau basis data. Perintah berikut menjalankan berkas tersebut dari terminal.

bash
# jalankan program pembersih dari folder tempat berkas disimpan
python3 bersih_log.py
text Keluaran
Baris asli : 2026-11-07 09:14:22   [sensor-03]   suhu=27.5C  kelembapan=68%  status=OK   # bacaan rutin pagi
Tahap 1    : ('2026-11-07', '09:14:22', 'sensor-03')
Tahap 2    : [('suhu', '27.5C'), ('kelembapan', '68%'), ('status', 'OK')]
Tahap 3    : 2026-11-07 09:14:22 [sensor-03] suhu=27.5C kelembapan=68% status=OK

Kesalahan umum#

Lupa awalan r pada pola. String pola yang ditulis tanpa awalan r memproses escape pada tingkat Python lebih dahulu. Akibatnya "\b" berubah menjadi karakter backspace sehingga pencocokan gagal tanpa pesan error, dan "\d" memicu SyntaxWarning pada Python 3.12. Tulis setiap pola sebagai raw string, misalnya r"\d+".

Titik yang tidak ditulis \.. Titik mencocokkan satu karakter apa pun kecuali baris baru. Pola 27.5 alih-alih 27\.5 juga cocok dengan 27x5, sehingga angka dapat salah terbaca secara diam-diam. Tulis titik literal dengan \. kecuali titik memang sengaja dibuat longgar.

Mengira re.match sama dengan re.search. Fungsi re.match hanya menguji kecocokan di awal string, sedangkan re.search memeriksa seluruh string. Pola suhu pada kalimat Budi mencatat suhu 27.5 gagal ditemukan oleh re.match karena kecocokannya berada di tengah kalimat. Gunakan re.search kecuali hanya posisi awal yang relevan.

Mengharapkan findall mengembalikan objek Match. Fungsi re.findall hanya mengembalikan string atau isi grup, sehingga m.start() tidak bisa dipanggil pada hasilnya. Apabila posisi setiap kecocokan diperlukan, gunakan re.finditer yang menghasilkan objek Match satu per satu. Kesalahan ini sering muncul setelah kode berpindah dari search ke findall.

Ringkasan#

  • Literal dicocokkan apa adanya, sedangkan kelas karakter melonggarkan satu posisi ke sekumpulan karakter yang diperbolehkan, termasuk kelas bawaan \d, \w, dan \s beserta negasinya.
  • Kuantifier +, *, ?, dan {m,n} mengatur jumlah pengulangan, dan bawaannya greedy sehingga kecocokan cenderung sepanjang mungkin.
  • re.search mengembalikan objek Match kecocokan pertama, re.findall mengumpulkan seluruh kecocokan, dan re.sub mengganti seluruh kecocokan.
  • Kombinasi pola bertahap dengan ketiga fungsi tersebut memulihkan baris log berantakan menjadi kepala log, pasangan kunci-nilai, dan teks bersih.

Referensi#