Kapan memakai regex
Regular expression adalah bahasa kecil untuk menggambarkan pola teks. Regex sangat kuat, dan mudah dipakai berlebihan.
Sebelum memakai re, tanyakan apakah method string biasa sudah cukup. .split(), .replace(), .startswith(), "target" in text: semuanya lebih cepat, lebih mudah dibaca, dan lebih jarang salah daripada regex yang setara. Simpan regex untuk saat pola yang kamu cari memang terstruktur tapi terlalu fleksibel untuk operasi string yang tetap: alamat email, nomor telepon, baris log dengan bentuk yang sudah diketahui, potongan HTML atau Markdown, dan pencarian "temukan hal semacam ini" lainnya.
Kosakata dasar
Sebuah pola regex adalah string yang menggambarkan apa yang kamu cari. Beberapa komponen dasarnya:
.: satu karakter apa saja\d: digit apa saja (0 sampai 9)\w: karakter "kata" apa saja (huruf, digit, garis bawah)\s: karakter spasi apa saja^: awal string$: akhir string[abc]: salah satu dari a, b, atau c[^abc]: karakter apa saja kecuali a, b, ca|b: a atau b*: nol atau lebih dari hal sebelumnya+: satu atau lebih?: nol atau satu{3}: tepat 3{2,5}: antara 2 dan 5( ... ): group (menangkap hasil yang cocok di dalamnya)
Itu sudah cukup untuk kebanyakan regex di dunia nyata.
Fungsi-fungsi utama
re.search(pattern, text) menemukan kecocokan pertama di mana saja dalam string. Fungsi ini mengembalikan objek match atau None:
Selalu pakai raw string (r"...") untuk pola regex. Kalau tidak, Python mencoba menafsirkan garis miring terbaliknya sebagai escape string, dan kamu mendapat pola yang berbeda dari yang kamu ketik.
re.match(pattern, text) mirip search, tapi hanya mencocokkan di awal:
Hampir selalu yang kamu butuhkan adalah search.
re.findall(pattern, text) mengembalikan semua kecocokan yang tidak saling tumpang tindih sebagai list:
Perhatikan bahwa findall mengembalikan string, bukan objek match. Kalau polamu punya satu group, kamu mendapat isi group itu. Kalau ada beberapa group, kamu mendapat list berisi tuple.
Capturing group
Tanda kurung di dalam pola menangkap apa pun yang cocok di dalamnya:
Group yang diberi nama biasanya lebih jelas:
Begitu regex-nya punya lebih dari satu group, memberi nama membuat kode pengambilannya jauh lebih mudah diikuti.
Mengganti dengan re.sub
re.sub(pattern, replacement, text) mengganti setiap kecocokan:
Kode itu membuang semua yang bukan digit. Teks pengganti bisa merujuk ke group yang ditangkap dengan \1, \2, dan seterusnya, atau di raw string, \g<1> lebih jelas:
Kamu juga bisa memberikan fungsi sebagai pengganti. Itu berguna untuk transformasi yang bukan sekadar tukar posisi:
Meng-compile pola untuk dipakai ulang
Kalau kamu memakai pola yang sama berkali-kali, terutama di dalam loop, compile pola itu sekali:
Pola yang sudah di-compile menyediakan method yang sama (search, match, findall, sub) tanpa pola sebagai argumen pertama. Sedikit lebih efisien, dan sering lebih mudah dibaca.
Flag
Pengubah yang umum, diberikan sebagai argumen flags= atau digabung dengan OR:
re.IGNORECASE(re.I): pencocokan tanpa membedakan huruf besar kecil.re.MULTILINE(re.M):^dan$cocok di setiap baris, bukan hanya di batas string.re.DOTALL(re.S):.juga cocok dengan baris baru (secara bawaan tidak).re.VERBOSE(re.X): mengizinkan spasi dan komentar#di dalam pola, supaya mudah dibaca.
re.VERBOSE sangat berguna untuk pola yang rumit:
Regex banyak baris yang diberi komentar jauh lebih mudah dirawat daripada satu baris yang sulit dipahami.
Greedy vs lazy
Quantifier (*, +, ?, {n,}) secara bawaan bersifat greedy: mencocokkan sebanyak mungkin. Tambahkan ? untuk membuatnya lazy:
Versi greedy menangkap seluruh substring dari <b> sampai </i>, mungkin bukan yang kamu mau. .+? yang lazy berhenti di > pertama.
(Catatan: jangan benar-benar mem-parse HTML dengan regex di produksi. Pakai html.parser atau BeautifulSoup. Contoh di atas hanya untuk menunjukkan sifat greedy.)
Contoh yang realistis
Mem-parse baris-baris dari format log sederhana:
Banyak sekali kemampuan dalam baris yang tidak seberapa.
Beberapa kebiasaan
- Selalu pakai raw string untuk pola.
- Mulai dari pola paling sederhana yang berhasil; perketat nanti.
- Pakai named group begitu kamu punya lebih dari satu group.
- Compile pola yang akan kamu pakai ulang.
- Regex lebih lambat daripada method string biasa. Kalau
.split()sudah cukup, pakai.split().
Berikutnya: error dan debugging
Itu menutup tur data sungguhan: file, JSON, CSV, HTTP, tanggal, dan regex. Tapi semua yang ada di program sungguhan cepat atau lambat akan bertemu error, dan membaca traceback Python dengan baik adalah keterampilan debugging terbesar yang bisa kamu kuasai. Bab terakhir membahas exception dan error spesifik yang paling sering akan kamu temui.
Pertanyaan yang sering diajukan
Apa itu regex di Python?
Regular expression (regex) adalah bahasa kecil untuk menggambarkan pola dalam teks. Module re di Python memungkinkan kamu mencari pola, mengambil potongan teks, dan mengganti hasil yang cocok. Regex berlebihan untuk operasi string sederhana (pakai dulu method string seperti .split() atau .replace()), tapi tidak tertandingi untuk pencocokan pola yang terstruktur.
Apa bedanya re.match dan re.search?
re.match hanya mencocokkan di awal string. re.search memindai seluruh string dan menemukan kecocokan pertama di mana saja. Kalau ragu, pakai search, karena lebih sesuai dengan intuisi manusia.
Apakah pola regex selalu sebaiknya ditulis sebagai raw string?
Ya. Pola regex sering berisi garis miring terbalik (\d, \s, \b), yang oleh string Python ditafsirkan sebagai escape sequence. Awalan r, seperti r'\d+', menyuruh Python membaca string-nya apa adanya, sehingga regex-nya sendiri tetap mudah dibaca.