Regular Expression

Regular expression (regex) adalah deretan karakter yang digunakan untuk pencarian string atau teks dengan menggunakan pola (pattern). Anda pasti familiar dengan cara penulisan email, misalnya duniaprogramming1@gmail.com

Kalau kita perhatikan, email memiliki pola : huruf / angka, diikuti oleh tanda @, kemudian diikuti huruf, tanda titik, dan kemudian huruf lagi.  Setelah mengetahui pola dari email, kita bisa mencari potongan teks mana saja yang termasuk email di dalam kumpulan teks yang banyak. Katakanlah kita ingin mencari email di dalam 10 lembar artikel yang tidak mungkin kita telusuri satu persatu secara manual.

Email hanya salah satu contoh. Tentu saja, semua teks memiliki pola, mulai dari nomor telpon, nomor KTP, tanggal, dan lain sebagainya.

Regex memudahkan kita mencari string tertentu dari teks yang banyak. Dengan regex, kita membuat pola terlebih dahulu. Kemudian nanti pola ini dicocokkan dengan teks atau tulisan yang panjang. Kalau dijumpai string yang cocok dengan pola, maka string tersebut pun bisa diekstrak atau diambil.

Python memiliki modul re untuk melakukan hal – hal yang berkaitan dengan regex. Tapi sebelum itu, kita harus mempelajari terlebih dahulu cara menggunakan regex ini.


Perbandingan Mencari Teks Tanpa Regex dan Dengan Regex

Berikut ini kita akan melihat contoh bagaimana  mendapatkan nomor telpon tanpa regex, dan akan kita  bandingkan dengan menggunakan regex.

Katakanlah nomor telpon rumah atau kantor adalah 10 digit, yaitu 3 digit lokasi diikuti oleh spasi dan 7 digit nomor pelanggan (kita misalkan ini hanya untuk kota besar yang memiliki 3 digit kode lokasi). Misalnya adalah nomor 061 7956411. Kita akan membuat sebuah fungsi is_phone_number() untuk mengecek apakah suatu teks adalah nomor telpon atau tidak.

Tanpa menggunakan regular expression maka jadinya adalah seperti berikut:

def is_phone_number(text):
    if len(text) != 11:
        return False
    for i in range(0, 3):
    if not text[i].isdecimal():
        return False
    if text[3] != ' ':
        return False
    for i in range(4, 11):
        if not text[i].isdecimal():
            return False
    return True

print('021 8229311 adalah nomor telepon:')
print(is_phone_number('021 8229311'))
print('Hello Hello adalah nomor telepon:')
print(is_phone_number('Hello Hello'))

Bila di jalankan, program di atas akan menampilkan hasil seperti berikut:

021 8229311 adalah nomor telepon:
True
Hello Hello adalah nomor telepon:
False

Fungsi is_phone_number() bisa kita pakai untuk mendapatkan beberapa nomor telepon yang ada di teks seperti berikut:

pesan = 'Panggil saya di nomor 061 7981011 besok. Kalau sore bisa hubungi kantor saya di 061 7939999.'
for i in range(len(pesan)):
    text = pesan[i:i+11]
    if is_phone_number(text):
        print("Nomor telepon ditemukan:", text)
    print("selesai")

Saat dijalankan program di atas akan menampilkan hasil seperti berikut:

Nomor telepon ditemukan: 061 7981011
Nomor telepon ditemukan: 061 7939999
selesai

Terlihat dari contoh, bahwa untuk mendapatkan nomor telepon, kita memerlukan banyak baris program. Hal ini sangat tidak efisien. Untuk mengatasinya kita bisa menggunakan regex.


Menemukan Pola Teks Menggunakan Regular Expression

Program di atas hanya bisa digunakan untuk mencari satu pola nomor telepon, tapi sudah membutuhkan banyak baris program. Bagaimana lagi dengan pola nomor telpon lainnya seperti (061) 7956411 atau tanpa kode daerah 7956411? Program di atas akan gagal memvalidasi nomor telepon tersebut.

Regex adalah pola teks. Misalnya untuk pola digit, kita menggunakan \d. Jadi misalnya pola untuk nomor telepon 061 7056123 kita bisa menggunakan \d\d\d \d\d\d\d\d\d\d. Kita bisa menyingkat lagi pola tersebut dengan yang lebih sederhana yaitu \d{3} \d{7} yang berarti 3 digit diikuti spasi dan diikuti oleh 7 digit.


Membuat Objek Regex

Sebelum bisa membuat regex di Python terlebih dahulu kita import modul re. Pada semua contoh di halaman ini, Anda harus terlebih dahulu mengimpor modul re.

import re

Untuk membuat pola regex, kita menggunakan metode compile() yang dimiliki oleh modul re. Metode compile() ini akan mengembalikan objek regex. Objek tersebut kita simpan dalam variabel untuk penggunaan selanjutnya. Untuk contoh pola telepon sebelumnya di atas bisa kita buat seperti berikut:

nomor_telepon_regex = re.compile(r'\d\d\d \d\d\d\d\d\d\d)

Catatan: Kita sebaiknya menggunakan karakter raw string r di depan string di dalam metode compile() untuk menghindari karakter escape. Bila tidak, maka kita harus mengetikkan karakter escape untuk karakter-karakter khusus, misalnya tanda \. Jadi \d\d\d harus dibuat menjadi \\d\\d\\d.


Mencocokkan Objek Regex

Setelah kita membuat objek Regex, maka selanjutnya kita sudah bisa menggunakannya. Objek regex yang kita buat tadi memiliki metode search() yang bisa kita pergunakan untuk mencari teks.

Bila tidak ada teks yang ditemukan, maka metode search() akan mengembalikan None. Bila ada teks yang sesuai pola, maka metode ini akan mengembalikan objek Match. Objek Match ini memiliki metode group() yang berfungsi untuk mengembalikan string sebenarnya yang sesuai dengan pola tadi. Cobalah ketikkan kode berikut di mode interaktif IDLE atau cmd:

>>> nomor_telepon_regex = re.compile(r'\d\d\d \d\d\d\d\d\d\d') 
>>> matching_object = nomor_telepon_regex.search('Nomor telepon saya: 061 7984611') 
>>> print('Nomor telepon ditemukan: ' + mo.group())

Output dari program di atas adalah seperti berikut:

Nomor telepon ditemukan: 061 7984611

Pada contoh di atas, kita membuat objek Regex atau pola nomor telepon menggunakan re.compile() dan menyimpannya di dalam variabel nomor_telepon_regex. Selanjutnya kita panggil metode search() yang dimiliki oleh objek nomor_telepon_regex. Karena ada pola yang ditemukan, maka ada objek Match yang dihasilkan. Kita simpan hasilnya di variabel match_object. Kemudian kita panggil metode match_object.group() yang hasilnya adalah nomor telepon yang ditemukan.


Ringkasan Penggunaan Regex di Python

Langkah – langkah penggunaan regular expression di Python adalah sebagai berikut:

1. Impor modul regular expression yaitu dengan perintah import re

2. Buat objek Regex menggunakan metode re.compile(). Jangan lupa menggunakan raw string r

3. Lewatkan string ke metode search() yang dimiliki oleh objek Regex. Hasilnya adalah objek Match

4. Panggil metode group() yang dimiliki oleh objek Match untuk mendapatkan teks yang sesuai.

 


Pengelompokan Menggunakan Tanda Kurung ( )

Misalkan pada nomor telepon 061 7954811, kita ingin memisahkan kode area 061 dari nomor telepon sisanya. Kita bisa membuat pengelompokan dengan pola (\d\d\d) (\d\d\d\d\d\d\d). Yang ada di dalam tanda kurung pertama adalah group 1 dan yang kedua ada di group 2, dan seterusnya bila ada tanda kurung lagi.

Selanjutnya objek string pada group 1 bisa kita panggil menggunakan metode group() dengan argumen nomor group. Bila kita mengosongkan argumennya, maka yang akan dikembalikan adalah string yang cocok keseluruhannya. Untuk jelasnya, ketikkan perintah – perintah berikut pada mode interaktif IDLE:

>>> no_telp_regex = re.compile(r'(\d\d\d) (\d\d\d\d\d\d\d)')
>>> mo = no_telp_regex.search('Nomor telepon saya 021 8273467.')
>>> mo.group()
'021 8273467'
>>> mo.group(1)
'021'
>>> mo.group(2)
'8273467'

Bila kita ingin mendapatkan hasilnya sekaligus dalam 1 tuple, kita bisa menggunakan metode groups(). Hasilnya bisa disimpan dalam beberapa variabel dengan teknik multipenugasan.

>>> mo.groups()
('021', '8273467')
>>> kode_area, no_telp = mo.groups()
>>> print(kode_area)
021
>>> print(no_telp)
8273467

Tanda kurung memiliki arti khusus dalam regex. Bila aslinya yang ingin kita cocokkan adalah tanda kurung, maka kita harus menggunakan karakter escape yaitu dengan tanda \.

>>> no_telp_regex = re.compile(r'(\(\d\d\d\)) (\d\d\d\d\d\d\d)')
>>> mo = no_telp_regex.search('Nomor telepon saya (021) 8273467.')
>>> mo.group(1)
'(021)'
>>> mo.group(2)
'8273467'

Karakter escape \( dan \) di dalam re.compile() akan cocok dengan karakter tanda kurung ( dan )


Mencocokkan Beberapa Kelompok Menggunakan Tanda Pipa |

Kita bisa menggunakan tanda pipa | untuk mencocokkan beberapa ekspresi. Misalnya regex r'Superman|Spiderman' akan cocok dengan string 'Superman' atau 'Spiderman'.

Bila kedua string Superman dan Spiderman ada di dalam string yang dicari, maka yang akan dikembalikan adalah yang pertama kali muncul. Perhatikan contoh berikut:

>>> hero_regex = re.compile(r'Superman|Spiderman')
>>> mo1 = hero_regex.search('Superman and Spiderman')
>>> mo1.group()
'Superman'
>>> mo2 = hero_regex.search('Spiderman and Superman')
>>> mo2.group()
'Spiderman'

Kita juga bisa menggunakan karakter pipa untuk mencocokkan salah satu dari beberapa pola. Misalnya, kita ingin mencocokkan salah satu dari 'Batman', 'Batcopter', 'Batmobile'. Karena semuanya diawali dengan Bat, kita bisa menggunakan awalan Bat sekali diikuti dengan akhiran-akhirannya dalam tanda kurung. Ketikkan perintah – perintah berikut di mode interaktif:

>>> bat_regex = re.compile(r'Bat(man|copter|mobile|bat)')
>>> mo = bat_regex.search('Batcopter sedang rusak')
>>> mo.group()
'Batcopter'
>>> mo.group(1)
'copter'

Metode mo.group() mengembalikan teks ‘Batcopter’, sedangkan mo.group(1) hanya mengembalikan 'copter' saja. Dengan menggunakan karakter pipa dan tanda kurung, kita bisa membuat beberapa pola pilihan yang ingin dicocokkan.

Bila yang kita ingin cocokkan adalah karakter | yang sebenarnya, maka kita harus menggunakan karakter escape untuk tanda pipa, yaitu \|.


Pencocokan Nol Atau Satu Kali Menggunakan Tanda Tanya ?

Tanda tanya bisa digunakan untuk pola opsional. Maksudnya adalah stringnya bisa ada atau tidak. Bisa 0 kali atau 1 kali. Tanda ? diletakkan setelah string atau group string yang bersifat opsional tadi. Untuk jelasnya perhatikan contoh berikut:

>>> bat_regex = re.compile(r'Bat(wo)?man')
>>> mo1 = bat_regex.search('Ada Batman di Gotham city')
>>> mo1.group()
'Batman'

>>> mo2 = bat_regex.search('Ada Batwoman di Gotham city')
>>> mo2.group()
'Batwoman'

Bagian (wo)? pada contoh di atas artinya bahwa  wo adalah opsional. Bisa tidak ada wo, atau bisa ada satu wo. Oleh sebab itu r'Bat(wo)?man' akan cocok dengan ‘Batman’ maupun ‘Batwoman’.

Untuk contoh nomor telepon, misalnya kode areanya adalah opsional, maka kita bisa melakukannya seperti berikut:

>>> no_telp_regex = re.compile(r'(\d\d\d)?\d\d\d\d')
>>> mo1 = no_telp_regex.search('Nomor telepon saya 021 8273467')
>>> mo1.group()
021 8273467

>>> mo2 = no_telp_regex.search('Nomor telepon saya adalah 8273467')
>>> mo2.group()
'8273467'

Bila yang kita ingin cocokkan adalah karakter ? yang sebenarnya, maka kita harus menggunakan karakter escape untuk tanda tanya, yaitu \?.


Pencocokan Nol, Satu Atau Beberapa Kali Menggunakan Tanda Bintang *

Tanda bintang * adalah karakter khusus yang digunakan untuk membuat pencocokan nol kali, satu, atau beberapa kali kemunculan string. Contohnya adalah seperti berikut:

>>> bat_regex = re.compile(r'Bat(wo)*man') 
>>> mo1 = bat_regex.search('Ada Batman di Gotham city') 
>>> mo1.group() 
'Batman' 

>>> mo2 = bat_regex.search('Ada Batwoman di Gotham city')
>>> mo2.group() 
'Batwoman'

>>> mo3 = bat_regex.search('Ada Batman di Gotham city')
>>> mo3.group() 
'Batwowowoman'

Perhatikan bahwa (wo)* cocok dengan perulangan wo berapa kali pun, sehingga r'Bat(wo)*man' akan cocok dengan ‘Batman’, ‘Batwoman’, ‘Batwowoman’, ‘Batwowowowoman’, dan seterusnya.

Bila yang kita ingin cocokkan adalah karakter * yang sebenarnya, maka kita harus menggunakan karakter escape untuk tanda bintang, yaitu \*.


Pencocokan Satu Atau Beberapa Kali Menggunakan Tanda Tambah +

Tanda tambah + digunakan untuk pola satu kali atau lebih. Kemunculannya harus ada minimal satu kali. Perhatikan contoh berikut:

>>> bat_regex = re.compile(r'Bat(wo)+man') 
>>> mo1 = bat_regex.search('Ada Batwoman di Gotham city') 
>>> mo1.group() 
'Batwoman' 

>>> mo2 = bat_regex.search('Ada Batwowowoman di Gotham city') 
>>> mo2.group() 
'Batwowowoman'

Regex r'Bat(wo)+man tidak akan cocok dengan ‘Batman’ karena harus ada minimal satu wo di dalamnya.

Bila yang kita ingin cocokkan adalah karakter + yang sebenarnya, maka kita harus menggunakan karakter escape untuk tanda tambah, yaitu \+.


Pola Berulang Menggunakan Tanda Kurung Kurawal { }

Kita bisa menggunakan tanda kurung kurawal untuk membuat pola berulang. Misalnya, regex r'(He){3}' akan sesuai dengan string 'HeHeHe' tapi tidak cocok dengan 'He' maupun 'HeHe'.

Kita juga bisa mengatur perulangannya berapa kali, berapa minimum dan maksimumnya. Regex r'(He){2,5}' akan cocok dengan ‘HeHe’, ‘HeHeHe’, ‘HeHeHeHe’, dan ‘HeHeHeHeHe’.

Selain itu, kita juga bisa mengosongkan angka depan atau belakangnya. Regex r'(He){,4} akan cocok dengan nol sampai 4 kali He, sedangkan r'(He){3,} akan cocok dengan 3 atau lebih He.

Perhatikan contoh berikut:

>>> he_regex = re.compile(r'(He){3}')
>>> mo1 = he_regex.search('HeHeHe')
>>> mo1.group()
'HeHeHe'

>>> mo2 = he_regex.search('He')
>>> mo2 == None
True

Pada contoh di atas, (He){3} cocok dengan 'HeHeHe', tapi tidak dengan ‘He'. Karena tidak cocok dengan 'He', maka hasil dari mo2 adalah nilai None.


Pola Rakus dan Tidak Rakus

Regex pada Python secara default bersifat rakus (greedy). Artinya, dalam dua atau lebih situasi yang  sesuai, maka regex akan memilih string yang paling panjang. Untuk jelasnya tentang hal ini, perhatikan contoh berikut:

>>> rakus_regex = re.compile(r'(He){3,5}')
>>> mo = rakus_regex.search('HeHeHeHeHe')
>>> mo.group()
'HeHeHeHeHe'

Dari contoh di atas, bisa di lihat bahwa objek Match mengembalikan ‘HeHeHeHeHe’ dan bukan ‘HeHeHe’, padahal ‘HeHeHe’ juga adalah yang pertama cocok dengan pola.

Untuk membuat regex bersifat tidak rakus (non greedy) atau memilih kecocokan string yang pertama, kita bisa menggunakan tanda tanya di ujung dari group regex. Perhatikan contoh berikut:

>>> rakus_regex = re.compile(r'(He){3,5}?')
>>> mo = rakus_regex.search('HeHeHeHeHe')
>>> mo.group()
'HeHeHe'

Pada contoh di atas terlihat, bahwa dengan menambahkan tanda tanya di ujung perulangan regex, kita bisa mencegah sifat rakus dari regex. Perlu diingat bahwa tanda tanya selain untuk mencegah sifat rakus regex, juga bisa digunakan untuk pencocokan opsional nol atau satu kali seperti sudah dijelaskan sebelumnya.


Metode findall()

Sebelumnya, kita hanya menggunakan metode search() untuk pencocokan. Bila misalnya ada beberapa string yang cocok, maka metode search() hanya mengembalikan kecocokan yang pertama kali dijumpai pada string. Perhatikan contoh berikut

>>> no_telp_regex = re.compile(r'\d{3} \d{7}')
>>> string = 'Rumah: 021 8237371 Kantor: 021 8237432'
>>> mo1 = no_telp_regex.search(string)
>>> mo1.group()
'021 8237371'

Bila kita ingin mendapatkan semua string yang cocok, maka kita bisa menggunakan metode findall(). Metode ini akan mengembalikan list yang berisi semua string cocok yang ditemukan – selama tidak ada group dalam regexnya. Bila ada group dalam regexnya, maka metode findall() akan mengembalikan list berisi tuple dari tiap grup string. Untuk jelasnya perhatikan contoh berikut:

>>> string = 'Rumah: 021 8237371 Kantor: 021 8237432'
>>> no_telp_regex = re.compile(r'\d{3} \d{7}') #tanpa grup
>>> mo = no_telp_regex.findall(string)
>>> mo
['021 8237371', '021 8237432']

>>> no_telp_regex = re.compile(r'(\d{3}) (\d{7})') #dengan grup
>>> mo = no_telp_regex.findall(string)
>>> mo
[('021', '8237371'), ('021', '8237432')

Kelas Karakter

Dari contoh – contoh sebelumnya, kita sudah mengetahui bahwa \d adalah sebagai pola untuk sebuah digit. Oleh karena itu \d adalah pengganti dari regex (0|1|2|3|4|5|6|7|8|9).  Regex \d adalah contoh dari kelas karakter. Kelas karakter digunakan sebagai shortcut dari pola regex. Python memiliki banyak kelas karakter, seperti ditunjukkan oleh tabel berikut:

Kelas Karakter Karakter Yang Direpresentasikan
\d Digit atau angka dari 0 s/d 9
\D Semua karakter selain digit 0 s/d 9
\w Semua huruf, digit, dan karakter underscore (_)
\W Semua karakter selain huruf, digit, dan underscore
\s Spasi, tab, dan karakter newline (baris baru)
\S Karakter selain spasi, tab, atau newline

Misalkan regex r'\d+\s\w+' akan sesuai dengan satu atau beberapa digit (\d+) – diikuti satu spasi atau tab (\s) – dan kemudian diikuti oleh karakter huruf, digit, atau underscore (\w+).

>>> sesuatu_regex = re.compile(r'\d+\s\w+')
>>> sesuatu_regex.findall('11 sepeda, 10 mobil, 9 pesawat, 8 komputer, 7 handphone')
['11 sepeda', '10 mobil', '9 pesawat', '8 komputer', '7 handphone'

Pada contoh di atas, metode findall() mengembalikan list yang berisi semua string yang cocok dengan regex.


Membuat Karakter Kelas Sendiri

Kita bisa mendefinisikan kelas karakter kita sendiri untuk digunakan pada regex. Kita mendefinisikan kelas karakter yang kita inginkan di dalam tanda [ ]. Seperti misalnya [aiueoAIUEO] akan cocok dengan semua huruf vokal baik kecil maupun besar. Perhatikan contoh berikut:

>>> vokal_regex = re.compile(r'[aiueoAIUEO]')
>>> vokal_regex.findall('Learning Python is VERY FUN')
['e', 'a', 'i', 'o', 'i', 'E', 'U']

Kelas karakter [a-z] akan sesuai dengan semua huruf kecil dari a sampai z.

Kelas karakter [a-zA-Z] akan sesuai dengan semua huruf baik besar maupun kecil.

Kelas karakter [a-zA-Z0-9] akan sesuai dengan semua huruf dan juga digit.

Untuk karakter – karakter kontrol seperti +, ., *, atau () dibuat apa adanya (tidak menggunakan tanda karakter escape \). Kelas karakter[0-5.*] akan sesuai dengan digit 0 sampai 5 dan juga tanda titik . dan tanda bintang *. Kelas karakter [a-h()] akan sesuai dengan huruf a sampai h dan juga tanda kurung ( dan ).

Kita juga bisa membuat kebalikan atau negasi dari kelas karakter dengan menggunakan tanda caret (^) setelah tanda pembuka [. Misalnya [^aiueoAIUEO] akan sesuai dengan semua karakter yang bukan vokal, seperti contoh berikut ini.

>>> konsonan_regex = re.compile(r'[^aiueoAIUEO]') 
>>> konsonan_regex.findall('Learning Python is VERY FUN') 
['L', 'r', 'n', 'n', 'g', ' ', 'P', 'y', 't', 'h', 'n', ' ', 's', ' ', 'V', 'R', 'Y', ' ', 'F', 'N']

 


Membuat Regex Awal dan Akhir Teks dengan Tanda Caret ^ dan Dollar $

Tanda ^ bisa juga digunakan untuk menandakan bahwa suatu string cocok hanya jika dimulai dengan pola tertentu. Misalnya, regex r'^Hello' hanya cocok dengan string yang di awali dengan  'Hello'.

Tanda $ digunakan untuk menandakan bahwa string cocok hanya jika diakhiri dengan pola tertentu. Misalnya, regex r'\d$' hanya cocok dengan string yang diakhiri dengan angka.

Kombinasi ^ di awal dan $ di akhir digunakan untuk menandakan bahwa sebuah string harus diawali dan diakhiri dengan pola tertentu. Misalnya, regex r'^\d+$' hanya cocok dengan string yang diawali dan diakhiri dengan satu atau beberapa angka.

Untuk jelasnya, perhatikan contoh berikut ini:

>>> awal_hello = re.compile(r'^Hello')
>>> akhir_angka = re.compile(r'\d$')
>>> angka_semua = re.compile(r'^\d+$')

>>> awal_hello.search('Hello World!')
<_sre.SRE_Match object; span=(0, 5), match='Hello'>

>>> akhir_angka.search('Nomor bus itu adalah 121')
<_sre.SRE_Match object; span=(23, 24), match='1'>

>>> angka_semua.search('1239876450')
<_sre.SRE_Match object; span=(0, 10), match='1239876450'>

Pada contoh di atas terlihat bahwa fungsi search() selalu mengembalikan objek Match yang berarti bahwa selalu ditemukan kecocokan sesuai dengan regex yang dibuat.


Karakter Wildcard

Karakter titik (.) dalam regex disebut karakter wildcard. Karakter titik akan cocok dengan semua karakter kecuali tanda newline. Perhatikan contoh berikut:

>>> ang_regex = re.compile(r'.ang')
>>> ang_regex.findall('Sang Bang mencari barang plang Cap 7ang.')
['Sang', 'Bang', 'rang', 'lang', '7ang']

Perlu diperhatikan bahwa karakter titik hanya cocok dengan satu buah karakter. Oleh karena itu pada contoh di atas, barang yang cocok hanya rang, dan plang yang cocok hanya lang. Bila yang kita ingin cocokkan adalah karakter titik yang sebenarnya, maka kita harus menggunakan karakter escape untuk tanda titik, yaitu \..


Mencocokkan Keseluruhan String Menggunakan Tanda Titik Bintang .*

Kadang kala kita ingin mencocokkan keseluruhan string, karakter apapun yang ada di dalamnya. Misalnya string 'Nama Depan: ', diikuti oleh string apa saja, diikuti string 'Nama Belakang: ', diikuti lagi oleh  string apa saja.

Keseluruhan string tersebut bisa kita cocokkan menggunakan tanda titik bintang (.*) yang berarti “semuanya”. Ingat sebelumnya bahwa tanda titik adalah regex untuk “semua karakter kecuali newline”, dan tanda bintang adalah regex untuk “nol atau beberapa karakter”.

Perhatikan contoh berikut ini:

>>> name_regex = re.compile(r'Nama Depan: (.*) Nama Belakang: (.*)')
>>> mo = name_regex.search('Nama Depan: Budi Nama Belakang: Susanti')
>>> mo.group(1)
'Budi'
>>> mo.group(2)
'Susanti'

Regex titik bintang menggunakan mode rakus (greedy). Regex ini akan mencocokkan string sebanyak mungkin sampai akhir string. Untuk menggunakan mode non-greedy, kita menambahkan tanda tanya menjadi .*?. Perhatikan contoh berikut untuk perbedaan mode greedy dan non-greedy.

>>> nongreedy_regex = re.compile(r'<.*?>')
>>> mo = nongreedy_regex.search('<Budi pergi> ke pasar.>')
>>> mo.group()
'<Budi pergi>'

>>> greedy_regex = re.compile(r'<.*>')
>>> mo = greedy_regex.search('<Budi pergi> ke pasar.')
>>> mo.group()
'<Budi pergi> ke pasar.>'

 


Mencocokkan Karakter Newline Menggunakan re.DOTALL

Regex titik bintang (.*) cocok untuk semua karakter kecuali tanda baris baru (newline). Untuk mencocokkan karakter newline, kita memberi argumen tambahan untuk re.compile() yaitu argumen re.DOTALL. Perhatikan perbedaan antara yang tidak menggunakan re.DOTALL dan yang menggunakannya dari contoh berikut:

>>> tanpa_newline = re.compile(r'.*')
>>> mo = tanpa_newline.search('Python adalah bahasa pemrograman.\nBahasa ini diciptakan oleh Guido van Rossum\nSekarang Python sudah terkenal')
>>> mo.group()
'Python adalah bahasa pemrograman'

>>> dengan_newline = re.compile(r'.*', re.DOTALL)
>>> mo = dengan_newline.search('Python adalah bahasa pemrograman.\nBahasa ini diciptakan oleh Guido van Rossum\nSekarang Python sudah terkenal')
>>> mo.group()
'Python adalah bahasa pemrograman.\nBahasa ini diciptakan oleh Guido van Rossum\nSekarang Python sudah terkenal'

Review Simbol Regex

Sejauh ini, kita sudah mempelajari banyak simbol regex. Berikut adalah tinjauannya:

  • ? mencocokkan nol atau satu kali pola
  • * mencocokkan nol, satu atau beberapa kali pola
  • + mencocokkan satu atau beberapa kali pola
  • {n} mencocokkan n kali pola
  • {n,} mencocokkan n kali atau lebih pola
  • {,m} mencocokkan 0 sampai m kali pola
  • {n,m} mencocokkan n sampai m kali pola
  • {n,m}? atau *? atau +? mencocokkan pola dengan mode non-greedy
  • ^spam berarti string harus diawali dengan spam
  • spam$ berarti string harus diakhiri dengan spam
  • . cocok dengan karakter apapun kecuali karakter newline
  • \d, \w, \s masing – masing cocok dengan digit, word, dan karakter kosong (spasi)
  • \D, \W, \S kebalikan dari \d, \w, \s yaitu selain digit, word, dan karakter kosong
  • [abc] cocok dengan karakter yang ada dalam tanda [ ]. Di contoh ini adalah karakter a, b, dan c
  • [^abc] cocok dengan karakter selain yang ada dalam tanda [ ]. Di contoh ini adalah selain a, b, dan c

Pencocokan Case-Insensitive

Normalnya, regex mencocokkan string persis sama dengan pola yang dibuat. Huruf besar dan kecil dianggap berbeda (case-sensitive). Jadi re.compile('Pythonindo') akan berbeda hasilnya dengan re.compile('pythonindo') ataupun re.compile('PYTHONINDO') dan seterusnya.

Untuk membuat regex yang case-insensitive, kita bisa menambahkan argumen kedua ke re.compile() yaitu dengan argumen re.IGNORECASE atau re.I. Contohnya adalah seperti berikut:

>>> python = re.compile(r'python', re.I)
>>> python.search('python is so fun').group()
'python'

>>> python.search('Python is so fun').group()
'Python'

>>> python.search('PYTHON is so fun').group()
'PYTHON'

Mengganti String Menggunakan Metode sub()

Regex bisa digunakan untuk mengubah objek yang cocok dengan objek yang lain. Caranya adalah dengan menggunakan metode sub(). Dengan metode ini, setiap string yang sesuai dengan pola akan digantikan dengan string yang kita inginkan.

Metode sub() membutuhkan dua argumen. Argumen pertama adalah string pengganti yang kita inginkan, dan string kedua adalah string pencarian. Metode sub() mengembalikan string pencarian dengan tiap objek yang cocok sudah diganti dengan string pengganti.

Perhatikan contoh berikut:

>>> name_regex = re.compile(r'Agen \w+')
>>> name_regex.sub('SENSOR', 'Agen Bob menyerahkan dokumen rahasia ke Agen Lance.')
'SENSOR menyerahkan dokumen rahasia ke SENSOR.'

Ada kalanya kita perlu mengganti bagian tertentu saja dari group string. Misalnya kita ingin menampilkan huruf pertama dari string yang cocok dan menyensor sisanya. Di sini kita bisa mengetikkan \1, \2, \3, dan seterusnya yang berarti “Group 1, 2, 3 biarkan apa adanya, sedangkan yang selanjutnya diganti”. Perhatikan contoh berikut:

>>> name_regex = re.compile(r'Agen (\w)\w*')
>>> name_regex.sub(r'\1****', 'Agen Bob memberi tahu Agen Suneo bahwa Agen Patrick adalah mata-mata.')
'B**** memberi tahu S**** bahwa P**** adalah mata-mata.'

Perhatikan dari contoh di atas, kita membiarkan group 1 tidak digantikan dan yang selainnya digantikan dengan tanda bintang.


Mengorganisir Regex Yang Kompleks

Kita bisa membuat komentar di dalam re.compile() untuk memudahkan kita menguraikan maksud dari regex yang kompleks. Caranya adalah dengan menambahkan argumen re.VERBOSE. Selain itu kita membuatkan pola regexnya dalam tanda kutip tiga (''') untuk membuatnya dalam beberapa baris.

Misalnya, regex untuk email seperti berikut:

email_regex = re.compile(r'([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+(\.[a-zA-Z]{2,4}))')

Regex tersebut bisa kita gantikan dengan yang berikut:

email_regex = re.compile(r'''(
    [a-zA-Z0-9._%+-]+       # username
    @                       # simbol @
    [a-zA-Z0-9.-]+          # nama domain
    (\.[a-zA-Z]{2,4})       # dot-something
    )''', re.VERBOSE)

Pada contoh di atas, tanda # di dalam regex akan diabaikan. Demikian pula dengan karakter kosong (spasi) ekstra di dalam string, akan diabaikan. Cara ini membuat kita lebih mudah mengorganisir regex sehingga lebih mudah dibaca.


Menggabungkan re.IGNORCASE, re.DOTALL, dan re.VERBOSE

Metode re.compile() hanya mengizinkan dua buah argumen di dalamnya. Bila kita membutuhkan re.IGNORCASE, re.DOTALL, dan re.VERBOSE dalam satu regex, kita bisa menggabungkannya dengan operator bitwise (|).

>>> python_regex = re.compile(r'python', re.IGNORECASE | re.DOTALL | re.VERBOSE)

 

Bagikan: