2.35. Dasar-dasar pola¶
Ekspresi reguler adalah bahasa kecil untuk mendeskripsikan string berdasarkan bentuknya daripada isinya yang tepat. Gunakan ketika sebuah string cocok jika dan hanya jika mengikuti sebuah pola yang bisa Anda deskripsikan tetapi tidak dapat Anda enumerasi -- "urutan angka diikuti oleh satuan", "baris yang dimulai dengan ERROR dan diakhiri dengan angka", "salah satu dari ekstensi file ini, dalam urutan apa pun, dengan awalan v opsional".
Gunakan re hanya ketika metode string biasa tidak mencukupi.
str.startswith(),str.endswith()-- menguji awalan atau akhiran tetap.in-- menguji apakah substring tetap ada.str.split(),str.find(),str.replace()-- bekerja dengan pembatas tetap.
Setiap metode tersebut lebih cepat, lebih mudah dibaca, dan lebih sulit salah daripada regex yang setara. Gunakan regex ketika bentuk string yang penting dan substring tepatnya tidak.
2.35.1. Empat hal yang akan Anda gunakan¶
Modul MicroPython re menyediakan empat hal:
re.compile()-- ubah string pola menjadi objek pola yang sudah dikompilasi yang dapat Anda gunakan kembali.re.match()-- coba pola di awal sebuah string. Pola dijangkarkan pada posisi 0.re.search()-- coba pola di mana saja dalam sebuah string. Mengembalikan pencocokan pertama.re.sub()-- temukan setiap pencocokan dan gantikan.
Perbedaan penting vs CPython: tidak ada re.findall, tidak ada re.finditer, tidak ada re.split di level modul (pola yang dikompilasi memiliki metode split sebagai gantinya), tidak ada re.fullmatch, tidak ada konstanta flag seperti re.IGNORECASE. Jika Anda ingin menggunakan salah satunya di CPython, buat yang setara dari re.search() dalam sebuah loop.
2.35.2. Pola pertama¶
Pola r'\d+' mencocokkan satu atau lebih angka:
>>> import re
>>> m = re.search(r'\d+', 'sensor reading 42 ok')
>>> m.group(0)
'42'
Beberapa hal yang perlu diperhatikan:
Pola ditulis sebagai raw string (
r'...') sehingga backslash dalam\dsampai kerealih-alih diproses sebagai escape string Python. Selalu gunakan raw string untuk pola regex.re.search()mengembalikan objek pencocokan jika berhasil danNonejika gagal. Selalu periksa sebelum memanggilmatch.group().m.group(0)adalah teks lengkap yang cocok dengan pola. Grup 1, 2, ... muncul kemudian, setelah pola berisi tanda kurung tangkapan.
Pola yang sama dengan re.match() mengembalikan None karena string tidak dimulai dengan angka:
>>> re.match(r'\d+', 'sensor reading 42 ok') is None
True
>>> re.match(r'\d+', '42 readings')
<match num=1>
2.35.3. Bagian-bagian dari sebuah pola¶
Pola yang paling berguna dibangun dari sekumpulan kecil bagian. Yang berfungsi di MicroPython:
Karakter literal -- karakter mana pun yang bukan khusus mencocokkan dirinya sendiri. hello mencocokkan hello.
Karakter khusus -- . ^ $ * + ? { } [ ] \ | ( ) semuanya memiliki arti di bawah. Untuk mencocokkan salah satunya secara literal, escapekan dengan backslash: \. mencocokkan titik literal.
Kelas karakter -- singkatan untuk kumpulan karakter umum:
\d-- digit mana pun0-9\D-- bukan digit mana pun\s-- karakter spasi putih mana pun (spasi, tab, baris baru)\S-- bukan spasi putih mana pun\w-- karakter "kata" mana pun: huruf, angka, garis bawah\W-- karakter bukan kata mana pun.-- karakter mana pun kecuali baris baru
Kuantifier -- berapa kali bagian sebelumnya harus cocok:
*-- nol atau lebih (serakah)+-- satu atau lebih (serakah)?-- nol atau satu{n}-- tepat n{m,n}-- antara m dan n (inklusif)
Menggabungkan: \d{3}-\d{4} mencocokkan tiga angka, tanda hubung, empat angka. \s+ mencocokkan satu atau lebih karakter spasi putih. hello.*world mencocokkan hello, apa pun (termasuk kosong), lalu world.
Catatan
Serakah berarti kuantifier mengonsumsi sebanyak mungkin input sementara masih memungkinkan sisa pola cocok. Terhadap hello x world y world, .* dalam hello.*world mencocokkan urutan terpanjang yang masih menyisakan world di akhir -- ia menangkap x world y, bukan yang lebih pendek x. Hal yang sama berlaku untuk + dan bentuk rentang {m,n}: mesin mengambil pencocokan terpanjang yang bisa, lalu mundur hanya jika sisa pola gagal.
2.35.4. Substitusi¶
re.sub() menemukan setiap pencocokan dan menggantinya dengan sebuah string. Pengganti dapat merujuk grup yang ditangkap melalui \1, \2, ... (dibahas bersama sisa sintaksis grup nanti). Tanpa grup, re.sub adalah temukan-dan-ganti langsung pada regex:
>>> re.sub(r'\s+', ' ', 'too many spaces')
'too many spaces'
>>> re.sub(r'\d+', 'N', 'log 12, log 345, log 6')
'log N, log N, log N'
Argumen ketiga adalah string yang dioperasikan; hasilnya adalah string baru dengan setiap pencocokan diganti.
2.35.5. Pemisahan -- hanya pada pola yang dikompilasi¶
Tidak ada re.split di level modul. Untuk memisahkan berdasarkan regex, kompilasi pola terlebih dahulu dan panggil metode split-nya:
>>> sep = re.compile(r'\s*,\s*')
>>> sep.split('a , b,c , d')
['a', 'b', 'c', 'd']
Argumen kedua opsional membatasi jumlah pemisahan:
>>> sep.split('a, b, c, d', 2)
['a', 'b', 'c, d']
2.35.6. Mengompilasi untuk digunakan kembali¶
Jika pola yang sama dijalankan berkali-kali -- di dalam loop atau dalam fungsi yang sering dipanggil -- kompilasi sekali dan gunakan kembali objek yang dikompilasi:
digit_run = re.compile(r'\d+')
def first_number(line):
m = digit_run.search(line)
return int(m.group(0)) if m else None
Memanggil pattern.match() dan pattern.search() pada objek yang dikompilasi sama dengan fungsi level modul tetapi melewatkan biaya kompilasi ulang pada setiap panggilan.
2.35.7. Pola yang tidak mencocokkan apa pun¶
Tiga pola khususnya sering membuat pengembang terkejut:
.*mencocokkan string kosong.re.search(r'.*', s).group(0)mengembalikan''untuk input apa pun.Pola dengan karakter khusus yang tidak di-escape adalah kesalahan sintaksis.
re.compile(r'cost: $5')memunculkanValueErrorkarena$berarti "akhir string". Gunakanr'cost: \$5'.Titik
.tidak mencocokkan baris baru. Untuk mencocokkan melewati baris baru, tulis pola untuk menanganinya secara eksplisit dengan[\s\S]atau berikan satu baris sekaligus.
Dengan bagian-bagian ini sebuah pola dapat mencocokkan hampir semua irisan teks berformat tetap. Menarik data terstruktur dari pencocokan membutuhkan grup tangkapan.