
String awal
Di bagian pertama kita telah berkenalan dengan 9 karakter meta dasar. Masih ingatkah Anda akan kesembilan karakter tersebut? (Eits, jangan mencontek, nanti lembaran majalah edisi 1 akan semakin habis terlepas-lepas.) Berikut saya ulang kembali. Harap karakter-karakter dasar ini Anda ingat baik-baik, karena akan sering sekali dijumpai dalam hampir setiap pola regex:
- | (garis vertikal) untuk pemilihan. a|b|c akan cocok dengan salah satu dari a, b, atau c.
- ( dan ) (kurung buka dan tutup) untuk pengelompokan. a(b|c) akan cocok dengan ab atau ac, tapi tidak dengan c, karena pola pemilihan b|c yang dirangkai dengan a. Pertanyaan 1: Bagaimana pola untuk mencocokkan “ab atau c”? (Jawaban di akhir tulisan)
- [ dan ] (kurung siku buka dan tutup) untuk membuat set karakter. Set karakter adalah deretan karakter alternatif pencocokan. Sama maksudnya dengan garis vertikal, namun set karakter hanya untuk memilih karakter tunggal dari serangkaian pilihan serta memiliki dua notasi pelengkap untuk mempersingkat yaitu rentang (mis: [a-z] untuk menyatakan “huruf kecil apa saja”) dan negasi ([^0-9] untuk menyatakan “bukan angka”).
- ? (tanda tanya) untuk mengartikan opsional, boleh ada boleh tidak. ma(ri)?lah dapat cocok dengan marilah atau dengan malah.
- . (titik) yang akan cocok dengan satu karakter apa pun. … berarti string apa pun boleh asal memiliki tiga karakter.
- * (bintang) untuk mengartikan nol atau lebih. selama(-lama)*nya dapat cocok dengan string selamanya, selama-lamanya, selama-lama-lamanya, dan seterusnya.
- + (plus) untuk mengartikan satu atau lebih. ((do|re|mi|fa|so|la|si)-)+ akan cocok dengan gumaman nyanyian apa saja, asal terdiri dari satu nada atau lebih. Misalnya (maaf) so-do-mi atau—Pertanyaan 2: coba tebak, potongan lagu Phil Collins manakah ini: so-so-mi-mi-re-re-do-re-re-mi. (Jawaban di akhir tulisan).
- ^ untuk penjangkaran di awal, yaitu menyatakan pola ini harus dicocokkan dengan awal string. ^angkat hanya akan cocok dengan angkat atau angkatlah, tapi tidak dengan mengangkat.
- $ untuk penjangkaran di akhir, yaitu menyatakan pola harus dicocokkan dengan potongan akhir string. angkat$ hanya cocok dengan angkat dan mengangkat, tapi tidak dengan angkatlah.
Yang Anda pelajari lagi di Bagian Pertama adalah bahwa karakter meta ini maknanya bergantung pada konteks. Di dalam set karakter [ ] misalnya, karakter $ bukanlah karakter meta, melainkan karakter literal biasa, sementara ^maknanya berubah menjadi berarti negasi dan bukan penjangkaran.
Quantifier
?, +, dan *sebetulnya adalah shortcut dari sebuah sintaks yang lebih umum, yaitu quantifier. Quantifier menyatakan berapa rentang jumlah yang diperbolehkan dari elemen yang di depannya. Format quantifier adalah salah satu dari:
- X{m}, artinya elemen X harus terulang sebanyak persis m kali.
- X{m,}, artinya elemen X harus ada minimal sebanyak m kali.
- X{,n}, artinya elemen X boleh ada hingga terulang maksimal n buah.
- X{m,n}, artinya elemen X boleh ada dari m hingga n buah.
Beberapa contoh:
- \d{5} cocok dengan bilangan 00000, 10000 hingga 99999 (semua harus terdiri dari digit sebanyak lima buah).
- \d{1,5} cocok dengan bilangan 0-99999 (mulai dari satu hingga lima digit).
- \d{1,} cocok dengan deretan digit, atau sama dengan pola \d+.
- ? sama dengan {0,1}, + sama dengan {1,} dan * sama dengan {0,}.
Pertanyaan 3: Apa pola untuk mencocokkan nomor ISBN? Anggaplah nomor ini sudah dibuang semua setripnya.
Escape
Karakter \(backslash, garis miring terbalik) boleh disebut karakter meta juga, meski orang biasa menyebutnya karakter pengescape. Garis miring terbalik ini perlu sekali untuk dua hal.
Pertama, untuk menjadikan karakter meta tepat di belakangnya menjadi literal. Katakanlah Anda ingin mencocokkan x^2. Bagaimana caranya, sementara ^ adalah karakter meta? Jawabnya dengan escape: x\^2. Contoh lain, Anda ingin mencocokkan angka desimal dengan pemisah titik. Bagaimana menyatakan “titik” yang betul-betul hanya cocok dengan sebuah titik literal, sementara karakter titik di pola itu amat gampangan, mau dengan siapa saja? Jawabnya adalah pola [0-9]+(\.[0-9]*)?dan bukannya [0-9]+(.[0-9]*)?(perhatikan perbedaannya pada backslash sebelum titik). Bagaimana bunyi pola ini? “Rangkaian satu atau lebih digit yang boleh diikuti oleh titik dan nol atau lebih digit lagi.” Contoh string yang cocok antara lain: 5, 0.3, 1012, dan 500.500. Tanpa backslash di depan titik, maka titik tersebut akan dianggap sebuah karakter meta, sehingga string seperti 0p3 atau 0-0 pun akan cocok.
Kedua, karakter \ dipakai sebagai awalan untuk menyatakan karakter yang tidak bisa dinyatakan langsung karena tidak tercetak, dsb. Beberapa di antaranya adalah: \tuntuk menyatakan Tab atau \nuntuk menyatakan newline (Enter). Pola \xNN atau \000dipakai untuk menyatakan karakter ASCII dengan kode heksadesimal (berbasis 16) atau oktal (berbasis 8). Contohnya: \x09dan \012 masing-masing berarti karakter Tab (kode 9 desimal/heksadesimal) dan karakter newline (kode 10 desimal, atau 12 bila dinyatakan dalam oktal). Di Perl dan fungsi preg_* PHP juga ada beberapa kombinasi shortcut lain yang menggunakan \. Lihat Tabel 1. Sementara Tabel 2 adalah daftar shortcut untuk regex aliran POSIX. Memang ada beberapa aliran—atau flavor—regex yang ada, masing-masing dengan sintaks yang dan fitur sedikit berbeda. Kita akan membahasnya nanti, tapi yang jelas kedua gaya shortcut di Tabel 1 dan 2 didukung oleh Perl dan fungsi preg_*PHP.
Pertanyaan 4: Pola yang menyatakan “bilangan bulat positif atau negatif”?
Pertanyaan 5: Pola untuk menyatakan variabel Perl/PHP, namun kini dinyatakan dengan shortcut?
Pertanyaan 6: Pola yang menyatakan sebuah “kata”?
Fasilitas Regex di Berbagai Bahasa
Saatnya kita mulai menggunakan regex di dalam bahasa pemrograman favorit kita. Regex tersedia di berbagai platform dan bahasa. Di Windows, fasilitas regex disediakan Microsoft dalam bentuk objek COM, sehingga selain di VB juga bisa diakses dari bahasa mana saja yang mendukung COM. Delphi misalnya, karena sayangnya hingga versi 6 belum juga memiliki dukungan regex yang built-in. Di Unix, ada library PCRE yang mendukung hampir semua sintaks regex Perl. PCRE adalah library C yang bisa dipakai oleh aplikasi dan bahasa mana saja, termasuk telah dipakai oleh PHP dan Python. Karena Unix adalah salah satu lingkungan awal tempat regex lahir dan tumbuh, maka Anda tak perlu kuatir karena regex dapat ditemui dan didukung di banyak tool—meski flavornya berbeda-beda. Mulai dari keluarga grep, sendmail dan procmail, editor joe/vim/emacs, dsb.
Dalam tutorial ini, saya akan membuat contoh-contoh dalam Perl, PHP, VBScript, dan Javascript. Untuk bahasa lainnya, harap lihat manual masing-masing.
Cara Kerja Regex
Sebelum membahas sintaks tiap bahasa, ada satu konsep yang perlu dijelaskan. Ada dua elemen yang terlibat dalam operasi regex. Pertama adalah polanya itu sendiri, yaitu sebuah string yang berisi deretan karakter, karakter meta, dan sintaks regex yang lain. Kedua adalah mesin regex, yaitu komponen yang ada di bahasa pemrograman atau aplikasi yang akan memroses pola tersebut. Mesin regex mula-mula akan membaca pola, lalu mengkompilasinya menjadi bentuk internal graf atau seperti peta berpanah. Misalnya, pola a|b akan diubah menjadi semacam bentuk bercabang dua. Selanjutnya, mesin regex akan mengambil string lalu memasukkannya ke dalam graph yang telah dibuat. Mesin regex akan berusaha melewatkan string ini melalui cabang-cabang yang sesuai dari titik masuk graf hingga titik akhir. Jika berhasil mencapai finish, maka string tersebut dikatakan cocok dengan pola. Jika gagal atau buntu, maka string dikatakan tidak cocok dengan pola. Mesin regex akan mencoba setiap cabang yang mungkin, bergerak mundur lalu mencoba cabang lainnya bila perlu, sampai tidak ada alternatif lagi yang memungkinkan. Karena itu semakin rumit dan panjang pola Anda, kemungkinannya adalah proses kompilasi dan pencocokan akan semakin lama. Tapi masalah optimasi kecepatan akan dibahas nanti, bukan sekarang.
Modifier i, s, m, g
Selama pencocokan, kelakuan mesin regex dapat diubah dengan modifier. Ada beberapa modifier yang dikenal dalam regex Perl-compatible. Yang pertama adalah i (IGNORE_CASE). Jika kita memberikan modifier ini, maka mesin regex tidak akan membedakan huruf besar dan kecil. Artinya, [A-Z] dalam mode i akan sama dengan [A-Za-z]. Modifier i dapat bermanfaat untuk memperpendek pola, jika kita menginginkan pencocokan yang tidak membedakan huruf besar kecil.
Modifier lain adalah s(SINGLE_LINE). Ingat karakter meta .(titik)? Menurut definisi, titik cocok dengan semua karakter. Tapi secara default mesin regex tidak akan mencocokkan titik dengan newline atau Enter. Jadi pola Selamat.+ akan cocok dengan string “Selamat datang” tapi tidak akan cocok dengan “Selamat\ndatang” (Selamat yang diikuti datang di baris berikutnya). Mengapa? Karena tanpa mode s, setiap akhir baris dianggap sebagai akhir string. Subpola .+ tidak kebagian karakter karena setelah Selamat tidak ada karakter lagi di baris pertama string. Namun dengan modifier s, .+ akan menelan semua sisa hingga akhir string (\ndatang) karena titik di mode s akan cocok dengan newline. Jadi, dengan kata lain, dalam mode s keseluruhan string dianggap terdiri dari satu baris.
Modifier m(MULTI_LINE) berfungsi untuk mengubah kelakuan karakter meta jangkar. (Meskipun namanya multiline, jangan dianggap kebalikan dari s. Keduanya dapat dipakai bersama-sama tanpa saling bentrok). Tanpa mode m, pola ^datangtidak akan cocok dengan string “Selamat datang” karena jangkar ^harus dicocokkan dengan awal string. Dalam hal ini awal string adalah Selamat. Namun dengan modifier m, pola tersebut akan cocok karena tiap awal dan akhir baris dianggap sebagai ujung yang bisa cocok dengan jangkar. Contoh lain, Selamat$ akan cocok di mode m tapi tidak tanpa m. Dengan kata lain, dalam mode m setiap baris dalam string akan dianggap masing-masin memiliki ujung.
Modifier g(GLOBAL_MATCH) terutama hanya berguna di Perl. Dengan modifier ini, pencocokan berikutnya akan dilanjutkan dari posisi terakhir, tidak diulang dari posisi awal string. Terutama berguna jika ingin mengiterasi string dari awal hingga akhir. Saya akan memperjelas keterangan ini nanti di bagian Perl.
Match Group dan Backtracking
Regex lebih dari sekedar menguji sebuah string terhadap pola dan mengeluarkan jawaban akhir ya atau tidak. Kita juga dapat mengambil sebagian atau keseluruhan string yang cocok dengan subpola untuk kita pakai semau kita. Dan nanti kita pun akan mempelajari cara mengganti string dengan string lain dalam topik Substitusi edisi mendatang.
Untuk mengambil subpola, kita menandainya dengan kurung (). Ingat tanda kurung? Selain sebagai pengelompokan, ia juga berguna untuk mengambil subpola. Pola (aku|kamu) dan aku|kamu dalam hal string mana saja yang cocok akan sama persis, tapi pola pertama sebagai tambahan akan mengambil substring yang cocok dan menyimpannya. Kumpulan string yang terjaring oleh () ini kadang disebut match group. Akan dijelaskan nanti di bagian tiap-tiap bahasa di bawah ini.
Elemen match juga dapat langsung disebutkan di dalam pola itu sendiri, di sebelah kanannya. Ini dinamakan backtracking, atau proses mengingat grup yang telah dicocokkan di bagian pola sebelumnya. Elemen pertama dinyatakan dengan \1, kedua dengan \2, dst. Misalnya, untuk menyatakan kata ulang, polanya adalah (\w+)-\1. Bunyi pola ini sebagai berikut: “deretan karakter dalam kata diikuti setrip dan diikuti kata yang sama.” Pola akan cocok dengan string "kuchi-kuchi hota hae" tapi tidak akan cocok dengan "warna-warni"(apalagi dengan "Pepeng"). Jika pencocokan dilakukan dengan modifier i, maka "Kuchi-kuchi hota hae"juga akan cocok.
Pertanyaan 7: Pola untuk menyatakan nama file yang mengandung string nama akhirannya (misalkan: txt-1.txt, mpg_itenas.mpg, atau bahkan Executeme.txt)?
Regex di Perl
Di Perl, ada enam operator yang berhubungan dengan regex: m//, s///, qr//, tr///, =~, !~. Empat operator pertama adalah operator yang dipakai untuk mengapit sebuah pola sementara dua yang terakhir untuk menempelkan string ke pola. Empat operator awal dapat muncul dalam berbagai penampilan, karena Perl mengizinkan tanda // diganti oleh karakter non-alfanumerik apa saja. Barangkali ini salah satu alasan mengapa orang sering menyebut kode Perl sulit dibaca bak line noise karena penuh dengan karakter-karakter non-alfanumerik. Namun fasilitas yang diberikan Perl ini kadang berguna untuk menghindari escaping yang terlalu banyak. Terlalu banyaknya \ di mana-mana juga mengganggu pandangan, dan kadang disebut orang dengan julukan backslashism atau toothpick syndrome. Ini karena /harus diescape juga jika kita menggunakan pengapit //, sehingga sering muncul pola-pola penuh garis seperti \/\/ untuk menyatakan dua garis miring literal, dst.
Operator m// digunakan untuk mencocokkan sebuah pola. Sintaksnya adalah sbb:
m/POLA/MODIFIER Khusus operator m//, selain dapat ditulis m##, m{}, m[], m<>, dsb. dapat juga ditulis hanya dengan //. Karena seringnya operasi pencocokan, maka di Perl dibuatkan bentuk ringkas khusus untuknya.
Seperti telah disebutkan sebelumnya, karakter /dalam POLA harus diescape jika pengapit adalah // juga. Ini tentunya untuk mencegah Perl bingung mana bagian dari pola dan mana akhir dari pola. Pola .+/.+ misalnya, jika diapit oleh // maka harus ditulis: /.+\/.+/. Dengan karakter garis miring terbalik, maka Perl jadi tahu bahwa garis miring sesudahnya itu bukan pengapit akhir, melainkan masih bagian dari pola. Contoh lain, pola http://[A-Za-z0-9]+(\.[A-Za-z0-9]+)*/setelah diapit harus ditulis: /http:\/\/[A-Za-z0-9]+(\.[A-Za-z0-9]+)*\//. Mata mulai berkunang-kunang karena pusing? Coba gunakan karakter pengapit lain seperti #, agar tidak perlu mengescape /. Ingat, jika karakter pengapit bukan /, maka m harus ada di depannya: m#.+/.+# dan m#http://[A-Za-z0-9]+(\.[A-Za-z0-9]+)*/#. Tentu saja, jika Anda misalkan memilih karakter pengapit :(titik dua), maka gantian tanda :di dalam pola kedua yang harus diescape.
MODIFIER boleh ada atau tidak, dan terdiri dari deretan huruf modifier seperti i, s, g, m yang telah kita bahas di bagian sebelumnya.
Tiga operator pengapit lainnya belum akan dibahas di sini. Selain keenam operator, fungsi split() dan grep() Perl juga menerima pola regex sebagai argumen. Selain itu terdapat fungsi pembantu quotemeta() yang akan dijelaskan nanti.
Operator =~ digunakan untuk mencocokkan sebuah string dengan pola. Sintaksnya sbb:
STRING =~ POLA Operator ini dapat mengembalikan dua jenis nilai. Yang pertama, jika di konteks skalar, nilai TRUE jika string cocok atau FALSE jika tidak cocok. Kedua, jika di konteks list, akan mengembalikan sebuah list berisi match group. Di Perl memang sebuah operator atau fungsi dapat mengembalikan dua jenis nilai, bergantung pada konteksnya.
Sintaks operator !~ sama dengan =~, hanya saja maknanya dibalik. Operator ini akan mengembalikan TRUE jika string tidak cocok dengan pola, dan sebaliknya FALSE jika cocok.
Contoh pertama:
$password = <STDIN>;
if ($password =~ /^$/) {
print "Password tidak boleh kosong!\n";
}
if ($password !~ /^\w{5,8}$/) {
print "Password hanya boleh 5-8 huruf, angka, dan _!\n";
} Baris pertama akan meminta kita mengetikkan password dan menangkapnya. Jika kita hanya menekan Enter, maka $passwordakan berisi "\n" saja, sehingga pengecekan regex pertama akan benar. Pengecekan regex kedua diberi jangkar untuk memastikan bahwa password berisi 5–8 karakter kata dan hanya itu saja. Jika kita tidak memberi jangkar, maka string seperti ---12345---pun akan cocok. Pola akan cocok dengan substring 12345. Tapi jika digunakan jangkar, maka pola harus dicocokkan di awal string, sehingga keseluruhan string tidak akan cocok.
Contoh kedua:
$teks = "saya bilang juga apa, ".
"dengan regex pemrosesan teks jadi mudah!";
$n = 0;
while ($teks =~ /(\w+)/g) {
print $1, "\n";
$n++;
}
print "Total = $n kata.\n"; Program di atas akan mengambil tiap kata dalam $teksdan mencetaknya ke satu baris terpisah. Hasilnya adalah sepuluh kata. Di sini kita melihat modifier g bekerja. Tanpa modifier ini, maka di setiap iterasi loop while hanya kata pertama yang akan terambil dan eksekusi akan terjebak selamanya di dalam loop. Coba saja sendiri.
Anda juga akan melihat variabel khusus bernama $1. Setelah tiap pencocokan, variabel ini akan diisi dengan elemen match pertama. Sisa match group, jika ada, akan berada di $2, $3, dst. Misalnya, jika pola Tanggal: /(\d+)-(\d+)-(\d+)/cocok dengan sebuah string, maka $1, $2, dan $3 akan diisi dengan deretan angka yang telah diambil dari string.
Program di contoh kedua tadi dapat juga dituliskan dengan gaya berikut:
$teks = "saya bilang juga apa, ".
"dengan regex pemrosesan teks jadi mudah!";
$n = 0;
while ( ($kata) = $teks =~ /(\w+)/g ) {
print $kata, "\n";
$n++;
}
print "Total = $n kata.\n"; Di dalam konteks list seperti di atas, match group hasil pencocokan akan langsung dikembalikan oleh operator =~sebagai list, yang lalu kita masukkan ke dalam variabel $kata. Jadi saat mencetak kata, kita tidak perlu menyebutkan $1 lagi, tapi bisa dengan $kata.
Bagaimana seandainya program pemecah kata ini harus ditulis dengan fungsi-fungsi string tradisional, akan berapa kali lipatkah jumlah baris yang harus ditulis? Apakah manfaat regex sudah mulai terasa bagi Anda? Jika belum, tenang saja, masih banyak sajian lain berikutnya yang akan mendemonstrasikan manfaat regex.
Regex di PHP
Di PHP tersedia dua flavor regex. Fungsi-fungsi dengan prefiks ereg_ dan eregi_adalah fungsi regex bergaya POSIX, sementara yang berprefiks preg_ bergaya Perl (menggunakan library PCRE). Regex Perl memiliki fitur-fitur lanjut seperti pencocokan takrakus, asersi, lihat-ke-belakang dan lihat-ke-depan, dsb. Meski sejauh ini sintaks-sintaks dasar yang dibahas di tutorial didukung oleh kedua gaya regex (kecuali modifier dan shortcut yang berbeda), saya akan memfokuskan pembahasan pada fungsi preg_*.
Berikut ini sintaks fungsi-fungsi PCRE di PHP:
int preg_match(str pola, str subjek[, array matches]);
int preg_match_all(str pola, str subjek, array matches[, int order]);
mixed preg_replace(mixed pola, mixed pengganti, mixed subjek[, int limit]);
array preg_split(str pola, str subjek[, int limit[, int flags]]);
string preg_quote(str s[, str kutip]);
array preg_grep(str pola, array input); Kali ini yang akan dibahas hanyalah preg_match()dan preg_match_all() dulu. Fungsi preg_match() di PHP sama dengan operator m// di Perl tanpa modifier g. Sementara preg_match_all() setara dengan operator m// dengan modifier g. Jadi di PHP tidak dikenal modifier g.
Pola ditulis sebagai string dengan diapit //atau pengapit lain. Jadi jika di Perl Anda menulis m/.+\/.+/, maka di PHP Anda menulis pola sebagai "/.+\/.+/". Perhatikan, harus dikutip. Modifier juga, seperti Perl, ditaruh di belakang pengapit terakhir, mis: "/perl/i". Jika di Perl Anda memperoleh match group di variabel khusus $1, $2, dst., maka di PHP Anda mendapatkannya dalam bentuk sebuah variabel array. Yang perlu dicatat, elemen ke-0 array ini akan berisi string yang cocok dengan seluruh pola, sementara elemen ke-1, dst baru berisi match group.
Contoh pertama:
if (preg_match("/(siemens|motorola) ([^,]+)/i",
"Nokia 8310, Siemens S45, Samsung SGH 100",
$matches)) {
echo "HP pilihanku = $matches[1] $matches[2]<br>\n";
echo “Sekali lagi, pilihanku = $matches[0]<br>\n";
} Kebetulan di contoh di atas kedua perintah echoakan menghasilkan keluaran string nama HP yang sama, karena $matches[0] berisi string yang cocok dengan keseluruhan pola.
Jika Anda tidak membutuhkan match group—yaitu jika hanya ingin menguji cocok atau tidak—maka Anda boleh tidak menyebutkan argumen ketiga ($matches).
Modifikasi contoh kedua program Perl sebelumnya:
$teks = "saya bilang juga tak apa-apa; mo Perl kek, PHP kek,".
" bahasa-bahasa laen kek, semua oke!";
$n = 0;
preg_match_all("/((\w+)-\2)/", $teks, $matches,
PREG_SET_ORDER);
for ($i=0; $i < size($matches); $i++) {
echo $matches[$i][1], "\n";
$n++;
}
echo "Total = ", size($matches), " kata ulang.\n"; Regex di Javascript
Regex telah didukung sejak Javascript 1.2, yaitu versi Javascript yang ada di Netscape 4.x dan IE4.
Di Javascript, regex diwakili oleh objek RegExp. Pertama-tama kita membuat objek RegExpdengan new atau dengan notasi // ala Perl. Untuk mengkompilasi pola, kita menggunakan metode compile(). Kompilasi eksplisit tidak wajib, namun dapat meningkatkan efisiensi. Untuk mencocokkan string dengan pola dan mengambil match groupnya, digunakan metode exec(). Atau untuk sekedar mengetes apakah string cocok atau tidak, gunakan metode test(). Match group dapat diperoleh di properti kelas (bukan properti objek) bernama $1, $2, dst. Jadi ini mirip dengan Perl. Javascript 1.3 mendukung semua sintaks regex yang telah dijelaskan sejauh ini (namun tidak mendukung modifier s dan m).
Modifier i dapat disebutkan di argumen constructor dan metode compile(), atau dengan mengeset properti objek ignoreCasemenjadi true. Demikian pula modifier g, dengan properti global.
re = new RegExp("pattern"[, "modifier"])
re = /pattern/modifier
re.ignoreCase = true | false
re.global = true | false
re.compile("pattern", "modifier")
re.test("string")
re.exec("string")
match_element1 = RegExp.$1 Contoh:
<script>
function checkUserName(v) {
re = /^[A-Za-z]{8}\d{4}$/;
return re.test(v);
}
function checkPin(v) {
re = /^\d{6}$/;
return re.test(v);
}
function checkForm(f) {
if (!checkUserName(f.username.value)) {
alert("Please enter a valid username!");
f.username.focus();
return false;
}
if (!checkPin(f.pin.value)) {
alert("Please enter a valid PIN!");
f.pin.focus();
return false;
}
return true;
}
</script>
<h2>Internet Banking</h2>
<form method=GET onSubmit="return checkForm(this)">
Masukkan username: <input name=username><br>
Masukkan PIN: <input type=password name=pin><br>
<input type=submit value=Login>
</form> Skrip di atas adalah contoh sederhana validasi sisi klien. Username dan PIN diuji harus dalam bentuk seperti yang dipakai oleh KlikBCA.
Regex di VBScript
Sintaks regex di VBScript kurang lebih sama dengan di Javascript/JScript. Terdapat objek RegExp yang dapat dibuat dengan new atau dengan notasi //. Untuk mencocokkan pola, terlebih dahulu Anda mengeset properti objek patterndengan pola. Lalu gunakan metode test().
Contoh:
<%
dim re
set re = new RegExp
re.pattern = "wget|pavuk|teleport|offline explorer"
re.ignoreCase = true
if re.test(Request.ServerVariables("HTTP_USER_AGENT"))
Response.Redirect "http://www.yahoo.com"
end if
%>
<h1>Isi asli</h2>
bla bla bla Skrip ASP di atas mengecek apakah User Agent yang dipakai oleh klien termasuk ke dalam salah satu daftar hitam yang tidak disukai. Jika ya, maka klien akan diarahkan ke tempat lain.
Jawaban Pertanyaan
- ab|c atau (ab|c). Tanda kurung tidak wajib di sini.
- You’ll Be In My Heart.
- Nomor ISBN terdiri dari sepuluh karakter, 9 digit dan 1 digit/huruf X sebagai checksum. Polanya sederhana saja: \d{9}[\dX]. Tentu saja untuk benar-benar mengecek apakah nomor ini valid atau tidak checksumnya, diperlukan lebih dari sekedar regex.
- Alternatif pertama: (\+|-)?\d+. Bunyi regex ini: “Tanda plus atau minus yang boleh mengawali deretan digit.” Perhatikan tanda plus kita escape karena sebetulnya dia adalah karakter meta. Alternatif kedua: [+-]?[0-9]+. Di sini kita menggunakan set karakter dan bukan shortcut. Sama saja, tergantung kesukaan Anda. Juga perhatikan tanda plus di sini tidak perlu diescape karena di dalam set karakter ia karakter biasa, bukan meta. Tapi mau diescape juga boleh, sama saja. Tantangan: Pola regex untuk bilangan bulat desimal sudah diberikan di sini. Bagaimana jika kita ingin mencocokkan juga notasi eksponen, mis: 2.2e+4 untuk menyatakan bilangan sebesar harga majalah ini, 22500? (Hint: man perldata).
- \$[A-Za-z_]\w*. Dengan shortcut, pola menjadi lebih ringkas. Tanpa shortcut polanya adalah \$[A-Za-z_][A-Za-z0-9_]*.
- “Kata” gampang-gampang sulit untuk dinyatakan dalam pola regex, bergantung pada jenis atau ruang lingkup yang Anda inginkan. Pola paling sederhana adalah \w+. Tapi pola ini akan menangkap juga semua deretan digit, karena \d tercakup dalam \w. Sebaliknya pola ini tidak mencakup kata seperti Jum’at atau aren’t karena kutip tunggal bukan bagian dari \w. Belum lagi ada pertimbangan apakah ingin mengambil kata ulang sebagai satu kata atau tidak. Jika tidak ingin menyertakan angka, Anda bisa membuat pola [A-Za-z_]+. Jika ingin menyertakan kata-kata dengan apostrof, gunakan pola \w+'\w+|\w+. Perhatikan bahwa subpola \w+'\w+ perlu ditaruh sebelum subpola \w+ karena jika tidak, yang terambil dulu hanyalah \w+ (hanya akan terambil Jum atau aren). Taruh pola yang lebih luas di kiri pola yang lebih sempit. Pola tadi tentu saja bisa juga ditulis \w+('\w+)?.
- ^[^\.]*([^\.]+)[^\.]*\.\1$. Mesin regex akan mencoba setiap kombinasi yang mungkin hingga string yang mungkin cocok pada akhirnya dapat cocok. Misalnya, untuk string "filetxt1.txt" mula-mula filetxt1 akan ditelan dulu oleh subpola [^\.]* yang pertama. Tapi setelah melihat tidak dapat cocok dengan subpola di kanannya, mesin regex akan mundur dan mencoba filetxt, filetx, filet, hingga file. Selanjutnya, txt1 akan ditelan oleh match group pertama. Tapi karena terakhirnya tidak bisa cocok dengan backtrack \1, maka mesin regex akan memundurkan match group pertama menjadi txt. Sampai di sini 1 akan cocok dimakan subpola ketiga, dan backtrack akan cocok sehingga seluruh pola cocok. Tapi Anda tak perlu pusing-pusing memikirkannya, semua sudah dilakukan mesin regex. Yang perlu Anda lakukan hanyalah membuat pola yang sesuai lalu serahkan pada mesin regex.
#: Hasil: Sisa: Kesimpulan:
1 ^ [^\.]* ([^\.]+) [^\.]* \. \1 $
filetxt1 .txt TIDAK COCOK
2 ^ [^\.]* ([^\.]+) [^\.]* \. \1 $
filetxt 1 . txt TIDAK COCOK
3 ^ [^\.]* ([^\.]+) [^\.]* \. \1 $
filetx t1 . txt TIDAK COCOK
4 ^ [^\.]* ([^\.]+) [^\.]* \. \1 $
filet xt1 . txt TIDAK COCOK
5 ^ [^\.]* ([^\.]+) [^\.]* \. \1 $
file txt 1 . txt COCOK Bahan Bacaan
Notasi [cd] berarti terdapat di CD majalah.
- PHP Manual, seksi Regular Expression Functions (Perl-Compatible) [cd]
- Javascript 1.3 Reference, Regexp Object [cd]
- How Regexes Work, Mark J. Dominus, perl.plover.com/Regex/
Posting Komentar