Monday, December 14, 2015

Cara Mudah Atasi Persoalan Regex

Terkadang saya mendengar keluhan dari rekan-rekan saya ketika mereka menemui permasalahan yang dapat dipermudah jika menggunakan regex. Keluhan-keluhan mereka biasanya merupakan ungkapan bayangan kengerian mereka ketika menggunakan regex. Menurut saya menggunakan regex tidak harus mengerikan, apalagi jika kita menggunakan regex tool yang tepat pengolahan teks menggunakan regex itu dapat menjadi menyenangkan!

Sebelum melanjutkan, saya ingin menegaskan artikel ini tidak akan membahas bagaimana cara menggunakan regex, ataupun membahas satu per satu bagaimana notasi regex pada setiap kasus di masing-masing bahasa pemrograman, karena cukup banyak artikel tutorial regex di Internet yang jauh lebih baik. Namun saya ingin berbagi bagaimana cara saya menyiasati persoalan yang terkait regex.

Metode yang saya lakukan dalam mengolah teks menggunakan pola regex dapat disederhanakan menjadi langkah-langkah berikut:
  1. Copy paste teks sumber yang akan dimanipulasi ke dalam pola regex
  2. Tambahkan tanda awal "^" dan akhiran "$", dan tambahkan modifier single line agar pola bekerja dalam mode single line
  3. Cari bagian-bagian teks utama yang akan diambil atau dijadikan patokan, jepit dengan kurung dan ubah teks utama menjadi notasi regex yang spesifik, misalnya format email, KTP, dsb.
  4. Ubah teks sebelum dan sesudah teks utama menjadi notasi regex yang cukup spesifik untuk menghindari kesalahan pola

Sejak beberapa bulan lalu, saya telah menggunakan online regex tool [1] yang bagus dan sangat membantu saya dalam melakukan pengolahan teks menggunakan regex. Silahkan kunjungi online tool tersebut dan coba untuk memahami masing-masing bagiannya. Artikel ini akan secara ekslusif menggunakan regex101 dalam mendemokan langkah-langkah yang saya gunakan.

Contoh: Mengambil Subset Teks

Contoh sederhana yang sering saya temui adalah bagaimana mengambil subset sebuah teks untuk digunakan di tempat lain. Misalnya ada sebuah teks "token: 12345678, username: okky, role: standard-user", dan kita diminta untuk mengambil nilai token "12345678" saja. Bagaimana pola regex yang tepat untuk digunakan? Mari kita buka regex101 dan masukkan teks ke field Test String dan field Regular Expression seperti gambar berikut ini.

Langkah pertama sudah saya jalankan pada gambar tersebut. Terdengar sederhana, namun dengan kita meng-copy-paste teks sumber ke pola regex awal, kita bisa lebih teliti mensubstitusi masing-masing karakter dengan notasi regex yang sesuai. Suatu ketika saya melewatkan langkah pertama ini, dan saya dihadapi oleh beberapa jam yang terbuang sia-sia, karena saya melewatkan beberapa karakter khusus yang seharusnya saya buatkan notasi regex-nya.

Tambahkan notasi awal dan akhir dan modifer single line. Daftar modifier bisa dilihat dengan cara meng-hover mouse ke tanda tanya di sebelah field modifer. Langkah ini semi opsional, namun pengalaman saya dengan menambahkan modifier ini hasil yang saya peroleh dapat lebih kosisten.

Di sini langkah ketiga jalankan dengan mencari bagian teks utama yaitu "12345678" yang berada persis setelah "token: ". Karena saya tahu bahwa nilai token itu pasti berupa 8 karakter numerik, maka saya substitusikan nilai token menjadi "\d{8}". Jalankan langkah ketiga hasilnya seperti ini:

Setelah mendapatkan informasi dari klien, ternyata urutan variabel belum tentu berurutan token, name, role. Tapi yang pasti pembedanya adalah tanda koma sebelum atau sesudahnya. Dengan demikian pada langkah terakhir kita coba spesifikkan dan sederhanakan pola regex-nya menjadi seperti berikut:

Pola regex akhir yang dihasilkan adalah /^.*,?token:\s*(\d{8}),?.*$/s yang kurang lebih berarti: "Cari kata token: bisa diikuti oleh whitespace (spasi, tab, new line, dsb.) berapapun karakternya, bisa didahului oleh tanda koma, kemudian diikuti oleh 8 karakter numerik dan bisa diakhiri oleh tanda koma". Untuk melihat apakah pola regex yang dihasilkan sukses, bisa lihat dari tanda hijau. Pada gambar berikut terlihat pola yang dihasilkan berhasil menemukan pola setelah 122 langkah. Semakin kecil jumlah langkah semakin efisien pola regex yang kita hasilkan.

Pada bagian kanan tengah terlihat pula matched group yang kita gunakan. Match group ini merupakan hasil dari match group yang kita beri tanda kurung pada pola regex kita dan dapat kita panggil dengan menggunakan "$1" atau "\1" atau group pertama dari object yang matched tergantung dari bahasa pemrograman yang digunakan.

Selama ini 4 langkah yang telah saya jabarkan secara singkat cukup untuk saya menangani berbagai pola regex yang saya temui. Adapun pernah saya menemui kasus yang tidak berhasil saya lakukan dengan langkah tersebut, biasanya saya coba mundur sejenak dan berusaha untuk menyederhanakan persoalan.

Perlu diingat, bahwa tidak selalu pengolahan teks berakhir dengan menggunakan regex. Regex akan lebih tepat jika digunakan untuk mengolah data yang tidak terstruktur seperti teks bebas, untuk pengolahan data yang terstruktur seperti XML, JSON, CSV, dsb., sebaiknya menggunakan parser dari masing-masing format data tersebut. Namun ada kalanya menggunakan parser justru membuat pengolahan teks membutuhkan memory yang besar karena masing-masing bagian akan dikonversi menjadi sebuah object. Biasanya terjadi pada kasus teks terstruktur dengan ukuran yang cukup besar. Salah satu solusinya adalah dengan memecah terlebih dahulu struktur besar tadi menjadi bagian-bagian yang kecil menggunakan regex jika dimungkinkan.

Sekian artikel saya kali ini, Happy Regexing!


No comments:

Post a Comment