14. Regular Expression

PHP: Belajar Regular Expression

Apa Itu Regular Expression?

Regular Expression atau biasa disingkat regex, adalah suatu metode untuk mengenali atau mendeteksi suatu pola tertentu pada suatu string.

Dengan menggunakan regex, kita bisa mendeteksi pola string seperti email, hashtag, link dan pola-pola kompleks lainnya dengan hanya satu ekpresi saja.

Ia juga merupakan metode standar dan independen, tidak mengenal bahasa pemrograman. Kita bisa mengimplementasi regex di berbagai macam bahasa pemrograman: termasuk PHP.

Kapan Harus Menggunakan Regular Expression?

Jika anda hanya butuh mendeteksi suatu kata statis dalam suatu string, jangan gunakan regex!

Tapi jika anda butuh untuk mendeteksi suatu pola yang dinamis dalam suatu string, maka anda tidak punya pilihan yang lebih baik dari pada regex.

Misalkan anda memiliki teks seperti ini:

*Kabarkan* kepada semua mahasiswa bahwa besok *kelas pemrograman web diliburkan*

Lalu anda ingin mencetak tebal semua karakter yang diapit dengan tanda bintang (**), sehingga teks di atas berubah menjadi seperti ini:

Kabarkan kepada semua mahasiswa bahwa besok kelas pemrograman web diliburkan

Maka cara terbaik untuk melakukan hal tersebut adalah: memanfaatkan regex.

Beberapa Fungsi Regular Expression Pada PHP

Di dalam PHP, terdapat beberapa fungsi yang berkaitan dengan penggunaan regex. Di antaranya:

FungsiDeskripsi
preg_match()Mencari kata/karakter yang sesuai dengan pola regex.
preg_match_all()Mencari semua kata/karakter yang sesuai dengan pola regex.
preg_replace()Mencari kata/karakter yang sesuai dengan pola regex, lalu menimpanya dengan data baru.
preg_grep()Mengembalikan kata/karakter yang sesuai dengan pola regex.
preg_split()Membagi string menjadi sebuah array menggunakan pola regex.

Table 1: fungsi-fungsi bawaan PHP untuk bekerja dengan regex

Beberapa Meta Karakter Regex

Terdapat banyak sekali meta karakter atau pola dalam regex. Akan tetapi, di bawah ini adalah yang mungkin paling sering anda gunakan.

KarakterDeskripsi
\skarakter putih (spasi, tab, baris baru)
\dangka digit (0-9)
\wkarkater huruf (a-z, A-Z, 0-9, _)
[aeiou]pola yang terdiri dari set karakter di dalam kurung siku
[^aeiou]pola yang tidak terdiri dari set karakter di dalam kurung siku
`(foobar

Table 2: beberapa meta karakter regex yang sering digunakan

Agar lebih mudah memahami regex, kita akan coba langsung mempraktikkannya. Kasus yang akan kita buat adalah:

  1. Deteksi #hashtag
  2. Deteksi @username
  3. Deteksi Email
  4. Dan Deteksi Kode Spesial Whatsapp

Langsung saja buka teks editor kalian, lalu buat 4 buah file sebagai berikut:

src/
├── fungsi
│   ├── deteksi-email.php
│   ├── deteksi-hashtag.php
│   ├── deteksi-kode-spesial-whatsapp.php
│   └── deteksi-username.php
└── index.php

Pada file index.php, require semua file yang berada pada direktori fungsi/.

<?php

require_once 'fungsi/deteksi-email.php';
require_once 'fungsi/deteksi-hashtag.php';
require_once 'fungsi/deteksi-kode-spesial-whatsapp.php';
require_once 'fungsi/deteksi-username.php';

Oke, setelah itu kita akan mulai dari setiap kasus.

1. Deteksi #hashtag

Kasus yang pertama adalah mendeteksi setiap kata yang diawali tanda pagar alias hashtag. Setelah berhasil mendeteksi, kita akan mereplace setiap hashtag menjadi link ke twitter.com.

Untuk mendeteksi pola hashtag, kita akan gunakan fungsi preg_match_all() yang akan mengembalikan semua teks yang sesuai dengan pola.

Buka file index.php. Lalu tambahkan kode berikut:

<?php

$teks1 = "Dihimbau agar seluruh masyarakat waspada akan #virus #corona 
yang akhir-akhir ini mulai menyebar.";

echo deteksiHashtag($teks1);

Pada file fungsi/detekksi-hashtag.php, buat fungsi deteksiHashtag(). Lalu kita coba untuk mendeteksi semua tanda # yang ada (sementara tanda pagarnya saja dulu)

<?php

function deteksiHashtag($input)
{
    $regex = "/#/";
    $hasil = [];
    
    preg_match_all($regex, $input, $hasil);

    # kembalikan data dalam bentuk json
    return json_encode($hasil);
}

Jika skrip index.php dijalankan, ia akan menghasilkan output sebagai berikut:

[["#","#"]]

Penjelasan:

  • Pola yang kita definisikan adalah /#
  • Pola tersebut hanya akan mencari tanda # yang ada pada variabel $input
  • Hasil kembaliannya, kita mendapatkan ada dua tanda pagar yang dikembalikan

Oke, sekarang kita akan kembangkan polanya menjadi sedikit lebih rumit. Kita akan memanfaatkan tanda kurung siku untuk menentukan set karakter pola untuk mendeteksi hashtag. Silakan lihat kembali ke tabel 2 untuk melihat deskripsi meta karakter yang ada.

Pada file fungsi/deteksi-hashtag.php, ubah variabel $regex menjadi seperti ini:

<?php

$regex = "/#[a-z]/";

Lalu jalankan lagi file index.php, kita akan mendapatkan output seperti berikut:

[["#v","#k"]]

Penjelasan:

  • di dalam variabel $regex, kita mendefinisikan pola yang berisi 2 karakter.
  • karakter pertama adalah tanda pagar
  • dan karakter kedua adalah set huruf dari a sampai z
  • sehingga hasil yang kita dapatkan adalah #v dan #k.

Pertanyaan: lalu bagaimana untuk mendeteksi semua karakter dalam satu kata yang ada?

Jawabannya adalah: dengan menambahkan tanda + setelah kurung siku!

Ubah variabel $regex menjadi seperti ini:

<?php

$regex = "/#[a-z]+/";

Lalu jalankan lagi aplikasi, dan sekarang kita berhasil mendapatkan output yang kita inginkan:

[["#virus","#corona"]]

Agar kita bisa mendeteksi hashtag yang juga berisi angka, huruf kapital serta underscore. Kita harus mengubah variabel $regex seperti berikut:

<?php

$regex = "/#[a-zA-Z0-9_]+/";

Oiya, satu lagi. Kita ingin hanya mendapatkan kata virus saja bukan #virus, begitu juga kata korona saja bukan #korona. Maka kita bisa memberikan tanda kurung untuk memisahkan satu elemen tertentu dari suatu pola regex.

Ubah variabel $regex menjadi seperti berikut:

<?php

$regex = "/#([a-zA-Z0-9_]+)/";

Jika kita eksekusi, kita akan mendapatkan output seperti berikut:

[["#virus","#corona"],["virus","corona"]]

Anda bisa perhatikan dari output di atas bahwa kita memiliki array dengan 2 item, di mana item pertama berisi pola secara lengkap. Dan item ke-2 berisi pola yang diapit oleh tanda kurung saja (tanpa tanda pagar).

Langkah selanjutnya, kita akan menggunakan fungsi preg_replace() untuk menimpa semua hashtag dengan sebuah link yang mengarah ke twitter.

Ubah fungsi deteksiHashtag() menjadi seperti berikut:

<?php

function deteksiHashtag($input)
{
    $regex = "/#([a-zA-Z0-9_]+)/";
    $timpa = "<a href='https://twitter.com/hashtag/$1'>$0</a>;";

    return preg_replace($regex, $timpa, $input);
}

Perhatikan baris yang saya highlight di atas:

  • $1 menandakan pola yang diapit oleh tanda kurung
  • sedangkan $0 menandakan pola secara keseluruhan
  • jika ada tanda kurung yang lain, maka anda bisa menggunakan variabel $2 untuk menampilkannya

Jika program saya eksekusi kembali, saya mendapatkan output seperti berikut:

Dihimbau agar seluruh masyarakat waspada akan #virus #corona yang akhir-akhir ini mulai menyebar.

2. Deteksi @username

Setelah mencoba langkah-langkah yang cukup detil pada contoh kasus pertama, saya rasa untuk kasus kedua tidak terlalu susah. Karena kita hanya perlu mengganti tanda # di atas menjadi tanda @. Lalu mengganti url twitter menjadi "https://twitter.com/$1".

Langsung saja.

Buka file fungsi/deteksi-username.php. Lalu tambahkan fungsi bernama deteksiUsername() sebagaimana berikut:

<?php

function deteksiUsername($input)
{
    $regex = "/@([a-zA-Z0-9_]+)/";
    $timpa = "<a href='https://twitter.com/$1'>$0</a>;";

    return preg_replace($regex, $timpa, $input);
}

Lalu pada file index.php, kita bisa menambahkan teks baru seperti berikut:

<?php

$teks2 = "Pak @jokowi telah menyampaikan #pidato yang berisi 
#himbauan kepada masyarakat untuk tidak banyak 
beraktifitas di luar rumah demi mencegah 
tersebarnya #virus #korona.";

echo deteksiUsername(
  deteksiHashtag($teks2)
);

Ketika saya eksekusi, ini adalah output yang saya dapatkan:

Pak @jokowi telah menyampaikan #pidato yang berisi #himbauan kepada masyarakat untuk tidak banyak beraktifitas di luar rumah demi mencegah tersebarnya #virus #korona.

3. Deteksi Email

Untuk mendeteksi email, kita bisa melakukannya dengan 3 pola bagian:

  • pola pertama adalah username email (sebelum tanda @). Pola ini adalah semua karakter dalam set [a-zA-Z0-9_] atau kita bisa singkat dengan menggunakan meta karakter \w.
  • pola yang kedua adalah tanda @.
  • pola yang ketiga adalah domain. Domain terdiri dari dari karakter huruf kecil dan titik ([a-z.]+)

Sehingga ketika 3 pola di atas kita rangkai, kita mendapatkan pola sebagai berikut:

<?php

$regex = "/[\w]+@[a-z.]+/";

Langsung saja. Silakan buka file fungsi/deteksi-email.php lalu buat fungsi deteksiEmail sebagai berikut:

<?php

function deteksiEmail($input)
{
    $regex = "/[\w]+@[a-z.]+/";
    $timpa = "<a href='mailto:$0'>$0</a>";

    return preg_replace($regex, $timpa, $input);
}

Lalu pada file index.php, kita bisa tambahkan teks baru sebagai berikut:

<?php
$tesk3 = "Untuk informasi lebih lanjut tentang pendidikan di Surabaya, 
anda bisa mengirimkan surel ke alamat dispendik@surabaya.go.id";

echo deteksiEmail($tesk3);

Maka setelah dijalankan, output yang kita dapatkan adalah sebagai berikut:

Untuk informasi lebih lanjut tentang pendidikan di Surabaya, anda bisa mengirimkan surel ke alamat dispendik@surabaya.go.id

4. Deteksi Kode Spesial Whatsapp

Kita telah mencoba 3 contoh kasus. Ketiga contoh tersebut terbilang sederhana karena ketiganya hanya menerapkan satu pola dan satu timpaan.

Sedangkan pada kasus ini, kita akan mencoba 3 pola sekaligus dalam satu kali pemanggilan fungsi preg_replace.

Selain menerima parameter string, fungsi preg_replace juga bisa menerima parameter berupa array yang berisi kumpulan lebih dari satu pola.

3 pola yang akan kita buat adalah sebagai berikut:

  • Double underscore (__): untuk mencetak miring.
  • Double bintang (**): untuk mencetak teks tebal.
  • Double gelombang (~~): untuk mencetak teks tercoret.

Langsung saja.

Buka file fungsi/deteksi-kode-spesial-whatsapp.php dan buat fungsi dengan nama deteksiKodeSpesialWA() lalu tuliskan kode program seperti berikut:

<?php

function deteksiKodeSpesialWA($input)
{
    $regex = [
        "/_([\w\s]+)_/",
        "/\*([\w\s]+)\*/",
        "/\~([\w\s]+)\~/"
    ];

    $timpa = [
        "<i>$1</i>",
        "<strong>$1</strong>",
        "<strike>$1</strike>"
    ];

    return preg_replace($regex, $timpa, $input);
}

Penjelasan:

  • variabel $regex dan $timpa berupa array yang berisi 3 buah item.
  • pola pertama dari array $regex akan ditimpa oleh string pertama dari array $timpa, dan begitu seterusnya.
  • meta karakter \w pada setiap pola di atas berarti [a-zA-Z0-9_].
  • dan meta karakter \s berarti karakter putih: yaitu spasi, tab, dan ganti baris.
  • kita menggunakan karakter putih karena bisa jadi yang diapit oleh tanda underscore/bintang/gelombang adalah kumpulan beberapa kata yang dipisahkan dengan spasi.

Setelah beres dengan fungsi deteksiKodeSpesialWA(). Sekarang kita ubah file index.php, tambahkan kode program berikut:

<?php

$teks4 = "_Bismillahirrahmanirrahim_.. Mohon maaf, sepertinya besok 
saya *tidak bisa hadir* ke kampus karena ~malas~ ada suatu 
kepentingan.";

echo deteksiKodeSpesialWA($teks4);

Bismillahirrahmanirrahim.. Mohon maaf, sepertinya besok saya tidak bisa hadir ke kampus karena malas ada suatu kepentingan.

Kode Sumber Lengkap

Kode sumber lengkap untuk tutorial ini dan seri tutorial PHP tingkat menengah lainnya bisa anda dapatkan di repositori github di sini.

Kesimpulan

Regex adalah suatu metode/pendekatan untuk mendeteksi suatu pola dari suatu string. Dengan memanfaatkan regex, kita bisa memeriksa berbagai macam pola teks yang rumit hanya dalam satu ekspresi saja.

Di dalama tutorial ini, kita telah mencoba 4 contoh kasus untuk memahami lebih jauh bagaimana cara bekerja dengan regex pada PHP.