Jump to content
Sign in to follow this  
slier

Tutorial: Panduan Regex

Recommended Posts

:bismillah:
:salam:

Ok first time buat tutorial...
Kali ni nak ajar regex atau nama panjangnya regular expression

Q : Apa itu regex?
A : Regex merupakan cara/kaedah yang biasa digunakan untuk melakukan pemprosesan keatas teks seperti mencari padanan(matches) dan penggantian(replacement)


Regex bisanya agak cryptic walaupun untuk yang dah mahir dengan regex..
So digalakkan gunakan tools yg sepatutnya semasa develope complex regex.

Tools:
1.gSkinner (online)
2.https://addons.mozilla.org/en-US/firefox/addon/2077/ (firefox addons)
3.Regex buddy (yang ni paling robust, but berbayar) Edited by slier

Share this post


Link to post
Share on other sites

Part 1- Anchor In Regex

Q : So apa itu anchor di dalam regex?
A : Ok anchor itu berfungsi seperti penanda/marker di mana kita mulakan/menamatkan carian di dalam text

Ada 8 jenis anchor:

1. ^
2. $
3. \b
4. \B
5. \A
6. \G
7. \z
8. \Z
^ bermaksud mulanya carian:
^a - bermaksud teks yang dicari haruslah bermula dengan character 'a'
Contoh:
/^a/ result ke atas subjek 'abc' = true (sebab subjek bermula dengan character 'a')
/^a/ result ke atas subjek 'bac' = false (sebab subjek bermula dengan chracter 'b')

 

$ bermaksud akhirnya carian
$a - bermaksud teks yang dicari haruslah diakhiri dengan character 'a'

 

cth:
/a$/ result ke atas subjek 'cba' = true (sebab subjek diakhiri dengan chracter 'a')
/a$/ result ke atas subjek 'abc' = false (sebab subjek tidak diakhiri dengan character 'a')

 

\b bermaksud sepadan antara teks yang melibatkan word boundary.biasanya melibatkan character 'space', 'new line' aka \n, dan 'line feed'
Antara character lain yang juga dikira sebagai word boundary adalah ` ~ ! @ # $ % ^ & * ) ( - + = \ | / > <
Jangan keliru dengan [\b] . [\b] mewakili backspace character

 

cth:
/\bxyz/ result ke atas subjek 'xyz' = true (sebab xyz bermula dengan word boundary 'new line');
/\bxyz/ result ke atas subjek ' xyz' = true (sebab xyz bermula dengan word boundary 'space chracter', perhatikan ada space sebelum character 'x');
/\bxyz/ result ke atas subjek 'abc xyz' = true (sebab xyz didahuli dengan word boundary 'space chracter', perhatikan space antara kedua perkataan)
/\bxyz/ result ke atas subjek 'axyz' = false (sebab xyz dimulai dengan bukan word boundary, ianya dimulai dengan literal character 'a')
/xyz\b/ sama seperti contoh pertama kecuali ianya harus diakiri dengan word boundary
result ke atas subjek 'xyz' = true (sebab xyz diakhir dengan word boundary 'line feed')
result ke atas subjek 'xyzz' = false (sebab xyz diakhir dengan bukan word boundary. tetapi dikahiri dengan literal character 'z')
/\bxyz\b/ bermaksud test subjek harus mengandungi charcter 'xyz' shaja (whole word only)
result ke atas subjek 'xyz' = true (sebab hanya mengadungi perkataan 'xyz')
result ke atas subjek 'axyzs' = false (sebab mengandungi perktaan selain dari 'xyz')

 

\B bermaksud sepadan antara teks yang melibatkan bukan word boundary.biasanya melibatkan literal character a-z, A-Z, 0-9'

 

cth:
/\Bxyz/ result ke atas subjek 'axyz' = true (sebab xyz bermula dengan bukan word boundary iaitu dengan literal character'a');
/\Bxyz/ result ke atas subjek ' xyz' = false (sebab xyz bermula dengan word boundary 'space chracter', perhatikan ada space sebelum character 'x');
/\Bxyz/ result ke atas subjek 'abc cxyz' = true (sebab xyz didahuli dengan bukan word boundary iaitu dengan literal character 'c', perhatikan space antara kedua perkataan)
/xyz\B/ sama seperti contoh pertama kecuali ianya harus diakiri dengan bukan word boundary
result ke atas subjek 'xyzk' = true (sebab xyz diakhir dengan bukan word boundary iaitu dengan literal character 'k')
result ke atas subjek 'xyz' = false (sebab xyz diakhir dengan word boundary 'line feed')
/\Bxyz\B/ bermaksud test subjek harus berada di tengah-tengah perkataan
result ke atas subjek 'axyza' = true (sebab 'xyz' diapit oleh character 'a')
result ke atas subjek 'xyz' = false (sebab hanya mengandungi perktaan 'xyz')
result ke atas subjek 'xyza' = false (sebab 'xyz' bermula dengan word boundary 'new line character')
result ke atas subjek 'axyz' = false (sebab 'xyz' diakhiri dengan word boundary 'line feed')

 

\A - berfungsi seperti ^ jadi tidak berapa penting untuk dibincangkan

 
 

\z dan \Z berfungsi seperti $
Tetapi ada perbezaan antara \z dan juga \Z
\z - akan match jika subjek test diakhiri tanpa new line character (carriaga return).Agak susah nak terangkan konsep ni..Biasanya bila kita sampai kehujung text kita akan tekan 'enter key' right.
so kalau kita guna \z, kita x akan match line yg ada 'new line chracter' dihujung teks tersebut.Harus diingat 'new line character' tidak dapat dilihat.Tapi percayalah ianya memang ada
\Z - akan match teks yang hujungnya ada 'new line character' ataupun tidak
$ - berfungsi seperti \Z tidak seperti \z

 

cth:
/abc\z/ ke atas subjek 'abc' = true (sebab 'abc' terletak dihujung subjek teks)
/abc\z/ ke atas subjek 'abc\n' = false (sebab 'abc' diakhiri dengan 'new line character'.setiap text editor mewakili baris baru (new line) dengan character '\n'. Dengan andaian user telah menekan enter pada hujung teks)
/abc\Z/ ke atas subjek 'abc' = true (sebab 'abc' terletak dihujung subjek teks)
/abc\z/ ke atas subjek 'abc\n' = true (sebab \Z juga akan match jika hujung subjek teks mengandungi 'new line' character aka '\n')

 

\G - mewakili posisi dimana padananan terakhir berlaku
- pada permulaan proses pemadanan, \G berfungis seperti \A

 

cth:
/\G\d\d/ ke atas subjek '1122aa33' = akan padan (match) 11 dan 22
pada permulaan padanan, \G match permulaan baris, selepas itu \d\d akan match 11, kemudian regex engine cuba untuk padankan character yang berikutnya.
Pada waktu ini \G mewakili kedudukan pada character kedua iaitu 1, selepas itu regex engine akan membuat padanan dan match 22.
Selepas itu regex engine cuba untuk membuat padanan lagi.Pada waktu ni \G mewakili kedudukan character keempat iaitu 2.
Regex engine cuba membuat padanan pada character 'aa' tetapi gagal kerana 'aa' bukanlah chacrter dari jenis nombor (\d)..jadi regex engine terus berhenti membuat padanan.
Jangan risau kalau agak kompleks..jarang kita guna anchor \G
Edited by slier

Share this post


Link to post
Share on other sites

Part 2 - Non Printing Character

Q : So apa itu Non Printing Character di dalam regex?
A : Bermaksud character yang tidak tercetak

Terdapat lebih kurang 10 non printing character, tetapi aku list 4 sudah memadai.
Character yang lain jarang digunakan.
 

1. \f
2. \n
3. \r
4. \t

 

\f - beraksud line feed
\n - bermaksud baris baru (new line)
\r - bermaksud carriage return (propietary to windose, best use with \n..most windose system use \r\n to donate new line)
\t - bermaksud tab

 

Contoh:

/abc\n/ ke atas subjeck 'abc' yg mempunyai new line character pada penghujung subjek memberi result = true
-cth bagi non printing character yg lain adalah sama seperti contoh di atas
Edited by slier

Share this post


Link to post
Share on other sites

Part 3 - Literal Character

Q : So apa itu Literal Character di dalam regex?
A : Bermaksud character yang tidak membawa maksud/nilai lepada regex engine.So boleh digunakan secara terus di dalam regex tanpa perlu di palang (excaped)
 

Senarai literal character:
a hingga z
A hingga Z
0 hingga 9
Selain dr $ ( ) * + . ? [ \ / ^ { | (seperti ! @ - dan sebagainya)


Contoh:

Untuk membuat padanan keatas 'abc' ,kita hanya guna /abc/
Untuk membuat padanan keatas 'hoi!' , kita hanya perlu guna /hoi!/
Untuk membuat padanan ke atas 'A.B' , kita perlu guna /A\.B/ (perhatikan character . perlu di palangkan terlebih dahulu sebelum digunakan)
Untuk membuat padanan ke atas '[email protected]' , kita hanya perlu guna /\w+@\w+\.\w+/
(perhatikan character @ tidak perlu dipalang terlebih dahulu sebelum digunakan, abaikan bahagian \w, \. dan + kerana ianya akan dibincangkan pada bahagian yg akan datang)
Edited by slier

Share this post


Link to post
Share on other sites

Part 4 - Non Literal Character

Q : So apa itu Non Literal Character di dalam regex?
A : Bermaksud character yang membawa/memberi maksud/nilai kepada regex engine.So tidak boleh digunakan secara terus di dalam regex.Perlu di palang(escaped '\') terlebih dahulu sebelum digunakan
 

Senarai non literal character:
$ ( ) * + . ? [ \ / ^ { |

 

Special Case:
Mungkin anda sedar character ']' dan character '}' serta character '-' tidak termasuk dalam senarai non literal character

Character ']' boleh digunakan secara terus tanpa perlu dipalang terlebih dahulu jika [ didalam regex telah di palangkan terlebih dahulu

Cth:
Untuk membuat padanan ke atas '[]', kita perlu gunakan /\[]/ , /\[\]/ juga padan(match) ke atas '[]'
Untuk membuat padanan ke atas ']' , kita perlu gunakan /\]/, tetapi jika regex digunakan seperti ini /]/ , padanan tidak akan dijumpai

Character '}' seperti character ']' , boleh digunakan secare terus jika, '{' didalam regex telah dipalangkan terlebih dahulu

Cth:
Untuk membuat padanan ke atas '{}', kita perlu gunakan /\{}/ , /\{\}/ juga padan(match) ke atas '{}'
Untuk membuat padanan ke atas '}' , kita perlu gunakan /\}/, tetapi jika regex digunakan seperti ini /}/ , padanan tidak akan dijumpai

Character '-' boleh digunakan secara terus tanpa perlu dipalang terlebih dahulu jika ianya digunkan di luar character class.
Walaupun digunakan di dalam character class, character '-' tidak perlu dipalang, tetapi amatlah digalakkan di palang terlebih dahulu supaya regex mudah dibaca
Chracter class merupakan chracter yang terletak didalam square baracket [], character class akan dibincangkan dalam bahagian yang akan datang

Untuk membuat padanan ke atas '2-1=1' tanpa menggunakan character class, kita perlu gunakan /2-1=1/
Untuk membuat padanan ke atas '2-1=1' dengan menggunakan character class, kita perlu gunakan /[1-2\-=]+/ , abaikan character + kerana akan dibincangkan pada bahagian yang akan datang

*Moral of the story - Do not over escape


Contoh:

Cara untuk membuat padanan ke atas '$10' , kita perlu menggunakan /\$10/
Cara untuk membuat padanan ke atas '1+1=2' , kita perlu menggunakan /1\+1=2/
Edited by slier

Share this post


Link to post
Share on other sites

Part 5 Character Class

Q : So apa itu Character Class di dalam regex?
A : Merupakan/mewakili senarai characters (series of characters) dan juga boleh mewakili jarak antara dua character (range between characters)

Characters class adalah character yang terletak didalam square brackets []
 

Senarai characters:
[adks] - mewakili character a,d,k,s
[%$#?] - mewakili chacracter %,$,#,? (perhatikan Non Literal character tidak perlu dipalang jika digunakan didalam character class, dalam contoth ini $ merupakan Non Literal Character)

 

Jarak antara characters:
Untuk menghasilkan jarak diantara dua character, kita perlu pisahkan kedua character tersebut dengan character sengkang (-)

[a-z] - mewakili characters antara 'a' hingga 'z'
[A-Z] - mewakili characters antara 'A' hingga 'Z'
[0-9] - mewakili nombor diantara 0 hingga 9
Menerbalikkan nilai character class (Negated character class)
Berfungsi untuk menerbalikkan nilai chacrter classs (membuat padanan kepada nilai yg tidak tersenarai di dalam character class)
Cara digunakan adalah dengan meletakkan character ^ di permulaan character class
Cth:
[^a-z] - mewakili character selain dari 'a' hingga 'z'
[^0-9] - mewakili character selain dari 0 hingga 9
Masaalah biasa dengan character class:
[A-z] - perhatikan chracter 'z', z adalah huruf kecil bukannya huruf besar, jadi character class ini mewakili chracter 'a' hingga 'z', 'A' hingga 'Z' dan juga character [ \ ] ^ _ `


Contoh:

/[asd]/ - akan padan(match) character 'a', 's' dan juga 'd'
/[$%!]/ - akan padan(match) character $, %, ! secara harfiah(literally)
/[a-Z]/ - akan padan(match) dari character 'a' hingga character 'z'
/[A-Z]/ - akan padan(match) dari character 'A' hingga character 'Z'
/[0-9]/ - akan padan(match) dari nombor 0 hingga nombor 9
/[^0-9]/ - akan padan(match) selain dari nombor 0 hingga nombor 9
Edited by slier

Share this post


Link to post
Share on other sites

Part 6 - Generic Character Types

 

Q : So apa itu Generic Character Types di dalam regex?

A : Merupakan singkatan(shortcut) untuk mewakili character class

Terdapat 6 Generic Character Types yang selalu digunakan
[code]
1. \d
2. \D
3. \s
4. \S
5. \w
6. \W
[/code]

[code]\d - mewakili character nombor antara 0 hingga 9
Nilai sepadan di dalam character class adalah [0-9][/code]

[code]\D - mewakili character selain dari nombor
Nilai sepadan di dalam character class adalah [^0-9]
[/code]

[code]\s - mewakili chracter space (jarak antara dua perkataan)
Nilai sepadan di dalam character class adalah [ ] ( perhatikan ada ruang kosong diantara [ dan juga ] )
[/code]

[code]
\S - mewakili character selain dari space
Nilai sepadan character class adalah [^ ]
[/code]

[code]
\w - mewakili character huruf, nombor dan juga sengkang
Nilai sepadan character class adalah [a-zA-Z0-9_][/code]

[code]
\W - mewakili chracter selain dari huruf, nombor dan jga sengkang (berlawanan dengan \w)
Nilai sepadan character class adalah [^a-zA-Z0-9_][/code]

[b]Contoh:[/b]
[code]/\d+/ - ke atas subjek 999 = true
/\d+/ - ke atas subjek 'abc' = false
/\D+/ - ke atas subjek 999 = false
/\D+/ - ke atas subjek 'abc' = true
/\s/ - ke atas subjek ' ' = true
/\s/ - ke atas subjek 'abc' = false
/\S/ - ke atas subjek ' ' = false
/\S/ - ke atas subjek 'abc1234' = true
/\w/ - ke atas subjek 'abc1234' = true
/\w/ - ke atas subjek '@#$&*' = false
/\W/ - ke atas subjek '@#$&*' = true
/\W/ - ke atas subjek 'abc1234' = false

Abaikan character '+' kerana ianya akan dibincangkan pada bahagian yang akan datang (+ mewakili ulangan (repetition) )
[/code]

Edited by slier

Share this post


Link to post
Share on other sites

Part 7 - Repetition


Q : So apa itu Repitition di dalam regex?
A : Berfungsi/digunakan untuk mengulang character

Boleh dikatakan ada 2 jenis repetion:
1.Menggunakan nombor
2.Menggunakan token

Repitition Menggunakan Nombor:
 

General Syntax:

*{min,max} - * menandakan apa juga character, min mewakili nilai minimum untuk membuat pengulangan dan max mewakili nilai maksimum untuk membuat pengulangan

 

Precise Syntax:

*{min,max} - digunakan untuk membuat pengulangan dalam julat tertentu, iaitu diantara nilai min dan nilai max

*{min} - digunakan untuk membuat pengulangan sebanyak nilai min

*{min,} - digunakan untuk membuat pengulangan sekurang-kurangnya nilai min dan semaksimum yg mungkin


Contoh:

/a{1,3}/ - ke atas subjek 'a' = true
/a{1,3}/ - ke atas subjek 'aaa' = true
/a{1,3}/ - ke atas subjek 'aaaa' = false

/a{2}/ - ke atas subjek 'aa' = true
/a{2}/ - ke atas subjek 'a' = false

/a{3,}/ - ke atas subjek 'aaa' = true
/a{3,}/ - ke atas subjek 'aaaaaaa' = true
/a{3,}/ - ke atas subjek 'aa' = false

 

Repitition Menggunakan Token:
Ada 3 jenis token yang digunakan untuk mewakili pengulangan

1. *
2. ?
3. +


Penerangan:

* - Mewakili pengulangan diantara 0 atau lebih character
- Merupakan pintasan kepada pengulangan menggunakan nombor {0,}

? - Mewakili pengulangan diantara 0 atau 1 character sahaja
- Merupakan pintasan kepada pengulangan menggunakan nombor {0,1}

+ - Mewakili pengulangan diantara 1 atau lebih character
- Merupakan pintasan kepada pengulangan menggunakan nombor {1,}

 

Contoh:

/a*/ - keatas subjek 'abc' = true
/a*/ - keatas subjek 'aabc' = true
/a*/ - keatas subjek 'xyz' = true

/a?/ - keatas subjek 'abc' = true
/a?/ - keatas subjek 'bc' = true
/a?/ - keatas subjek 'aabc' = false

/a+/ - keatas subjek 'abc' = true
/a+/ - keatas subjek 'aabc' = true
/a+/ - keatas subjek 'xyz' = false


Perhatian Tentang Pengulangan:
Secara semulajadi, setiap ulangan yang dilakukan menggunakan token adalah GREEDY(tamak).Bermaksud setiap token cuba untuk membuat ulangan sebanyak yang mungkin

Contoh:
Katakan kita hendak membuat padanan ke atas setiap html tag menggunakan contoh dibawah:

<h1>Ini Adalah Tajuk</h1>

Jadi kita cuba untuk mendapatkan tag <h1> dan juga </h1>

Jika kita menggunakan /<.+>/ , result yang kita dapat ada keseluruhan tag dan juga teks yang dikandungi olehnya <h1>Ini Adalah Tajuk</h1>

Sememangnya bukan ini yang kita mahukan

Sebabnya adalah kerana token .+ , ini kerana token dot (.) mewakili semua character selain character baris baru dan token '+' menyebakan token dot (.) diulang sebanyak yang mungkin,dan dalam kes ini ulangan dilakukan sehingga ke penhujung teks

Untuk memahami lebih lanjut kita perlu ketahui bagaiman regex engine berkeja


Cara Regex Engine Berkeja:
Token pertama iaitu < akan membuat padanan kepada character pertama didalam subjek '<h1>Ini Adalah Tajuk</h1>'.

Token yang seterusnya iaitu token dot (.) Token ini akan diulang menggunakan token +.Ini adalah token yang greedy.Dengan itu regex engine akan membuat ulangan sebanyak yang mungkin

Token dot (.) dapat membuat padanan keatas character 'h' didalam subjek, jadi regex engine terus untuk membuat padanan keatas character yang seterusnya iaitu character '1',padanan dapat dilakukan

Regex engine akan terus membuat padanan untuk character yang seterusnya, character yg seterusnya adalah >.Disini kita boleh nampak masaalah yang timbul. token dot (.) tersebut membuat padanan ke atas character > dan regex engine terus untuk membuat padanan.Token dot (.) akan terus membuat padanan hingan ke penghujung teks.Sampai di penghujung teks, token dot (.) tidak dapat untuk membuat padanaan, jadi regex engine akan membuat padanan menggunakan baki token yang terdapat didalam regex token iaitu token >

Setakat ini token <.+ telah membuat padanan ke atas '<h1>Ini Adalah Tajuk</h1>' dan regex engine telah sampai ke penghujung teks, jadi regex token > tidak dapat membuat padanan.

Apabila regex engine gagal untuk membuat padanan, regex engine akan melakukan backtrack (patah balik ke character sebeleumnya).

Dalam kes ini backtrack akan patah balik 1 character kerana token dot (.) mewakili 1 character, jadi padanan <.+ dikurangkan kepada '<h1>Ini Adalah Tajuk</h1'

Token didalam regex tetap > dan character terakhir didalam teks adalah '1', jadi regex engine cuba membuat padanan ke atas character seterusnya didalam teks dan dapat membuat padanan (dapat membuat padanan keranan character yg datang selepas character '1' adalah character '>')


Menjadikan Pengulangan 'Lazy'

Syntax:
1. +?
2. *?
3. ??


Ramuan terbaik untuk menyelesaikan masaalah kita tadi adalah menggunakan 'lazy repitition'.

Jika kita menggunakan /<.+?>/ , result yang kita dapat adalah '<h1>' , '</h1>'

Penerangan:
Sekali lagi < akan membuat padanan keatas character pertama didalam teks

Regex token yang seterusnya adalah .+? , ini adalah pengulangan secara malas (lazy repition)

Apa yang berlaku adalah regex engine cuba membuat ulangan yang paling sedikit, dalam kes ini , cuma 1 character sahaja (ini kerana + akan match sekurang-kurangnya 1 character)

Setakat ini <.+? membuat padanan keatas '<h', regex token yang seterusnya adalah >, regex engine cuba membuat padanan ke atas character yang seterusnya didalam teks iaitu character '1'

Regex engine gagal membuat padanan, dalam kes lazy repition, apabila regex engine gagal membuat padanan, backtrack juga akan dilakukan tetapi agak berbeza dengan backtrack didalam greedy repitition

Dalam lazy repitition, regex engine akan backtrack dengan mengarahkan regex token yg sebelumnya iaitu token .+? untuk menambahkan/memperbesarkan padanan yg telah dilakukannya

Dalam kes ini .+? akan membuat padanan ke atas character yang seterusnya dia dalam teks iaitu '1'

Jadi regex engine kembali ke token > dan cuba membuat padanan, setakat ini <.+? membuat padanan ke atas '<h1' jadi regex engine dapat membuat padanan ke atas character seterusnya diadalam teks (ini kerana character yang datang selepas character 1 adalah character > )


Moral of the story: Kalau kita berhati-hati dengan greedy repitition kita akan dapat mengoptimasi keupayaan regex engine dan memendekan masa regex engine membuat padanan
Disclaimer:Jangan bimbang kalau tidak paham greedy/lazy repitition

Edited by slier

Share this post


Link to post
Share on other sites
Part 8 - Grouping

Q : So apa itu Grouping di dalam regex?
A : Mempunyai 2 fungsi iaitu:
  • Digunakan untuk merangkumkan regex token ke dalam kumpulan bagi membolehkan regex operator itu berfungsi ke atas kumpulan tersebut daripada berfungsi keatas character itu sendiri.
  • Menghasilkan backreferences.
  • Cara Penggunaan:
    Untuk membuat grouping, kita perlu masukkan regex token ke dalam pasangan ( )

    Contoh:
    /ak{3}/ - akan membuat padanan ke atas subjek akkk ({3} hanya dikira kepada character k sahaja)
    /(ak){3}/ - akan membuat padanan ke atas subjek akakak ({3} berfungsi keatas character ak )
    /(xy)+/ - akan membuat padanan ke atas subjek xy, xyxy, xyxyxy
    

    Backreference
    Q : So apa itu Backreferences di dalam regex?
    A : Backreferences berfungsi seperti memori dimana ianya menyimpan padanan yang dibuat daripada grouping supaya ianya boleh digunakan semula didalam regex itu sendiri ataupun keatas result yang datang dari regex (biasanya dalam kes search dan replace)

    Contoh:
    /([a-z]+)@[a-z]+\.[a-z]+/ - akan membuat padanan keatas subjek [email protected] dan backreference yang disimpan adalah 'slier'
    

    Penerangan:
    Kenapa backreference menyimpan 'slier'
    Perhatikan token [a-z]+ , token ini membuat padanan keatas subjek 'slier' dan disebabkan padanan ini berlaku didalam goruping, backreference telah disimpan ( rujuk part 7 untuk memahami pasal token +)


    Grouping tanpa Backreference:
    Disebabkan grouping menghasilkan backreference, banyak kerja yang perlu dilakukan oleh regex engine, jadi dalam erti kata lain akan menyebabkan regex engine jadi perlahan
    Cara untuk membuat grouping tanpa menghasilkan backreference adalah dengan meletakkan ?: pada permulaan grouping

    Contoh:
    /(?:[a-z]+)@[a-z]+\.[a-z]+/ - akan membuat padanan keatas subjek [email protected] dan tiada backreference yang dihasilkan
    

    Menggunakan Backreference:
    Katakan kita hendak mencari padanan untuk setiap html tag:
    Contoh untuk membuat padanan keatas <b>howdy world</b> , kita mungkin akan menggunakan regex seperti dibawah:
    /<[a-z]>.*</[a-z]>/
    

    Ya, regex di atas memang akan membuat padanan ke atas <b>howdy world</b>
    Tetapi fikir sekali lagi, regex diatas juga akan membuat padanan ke atas <b>howdy world</i> , <b>howdy world</a> dan sebagainya
    Jadi untuk memastikan yang tag html yang penagkhiran bersamaan dengan permulaan tag html (senang cerita <b> harus diakhiri dengan </b> bukan dengan </a> dan sebagianya) kita perlu menggunakan backreferences

    Menggunakan backreferences:
    Backreferences digunnakan dengan menggunakan token \n ,dimana n mewakili nombor group dari kiri yang membuat backreferences (group yang tidak membuat backreferences tidak termasuk dalam pengiraan)

    Contoh:
    /(x)(y)/ - (x) = backrefenrences 1 , (y) = backrefenrences 2
    /(x)(?:y)(z)/ - (x) = backrefenrences 1 , (z) = backrefenrences 2
    

    Jadi didalam kes membuat padanan tag html, regex yang perlu digunakan adalah:
    /<([a-z])>.*</\1>/ - membuat padanan keatas <b>howdy world</b> sahaja
    
Edited by slier

Share this post


Link to post
Share on other sites

Part 9 - Lookahead and Lookbehind Assertion
 
 
Q : So apa itu Lookahead dan Lookbehind assertion didalam regex?
A : Lookahaed/Lookbehind bermaksud mencari/membuat padanan pada lokasi-lokasi tertentu didalam teks samaada padanan yang dicari diikuti oleh pattern yg tertentu (untuk Lookahaed) ataupun padanan didahuli oleh pattern yg tertentu (untuk Lookbehind)
 
Perbezaan antara Lookahaead dan Lookbehind
 
Lookahaed:
Mencari pattern selepas tempat padanan dibuat/lokasi semasa
 
Lookbehind:
Mencari pattern sebelum tempat padanan dibuat/lokasi semasa
 


Jenis-jenis Look Around Assertion
Terdapat 4 jenis Look Assertion iaitu:
 
Positive Lookahaed
Syntax: (?:pattern) - Tentukan samaada padanan diikuti oleh pattern
Contoh:  /a(?=b)/ - tentukan samaada 'a' diikuti oleh 'b'
 
 
Negative Lookahead
Syntax: (?!pattern) - tentukan samaada padanan tidak diikuti oleh pattern
Contoh: /a(?!b)/  -  tentukan samaada 'a' tidak diikuti oleh 'b'
 
 
Positive Lookbehind
 Syntax:  (?<=pattern) - tentukan samaada padanan didahului oleh pattern
 Contoh: /(?<=a)b/ - tentukan samaada 'b' didahului oleh 'a'
 


Negative Lookbehind
Syntax: (?<!pattern) - tentukan samaada padanan tidak didahului oleh pattern
Contoh: /(?<!a)b/ - tentukan samaada 'b' tidak didahului oleh 'a'
 

 

Lookaround Assertion Adalah Zero Width
Lookahead/LookBehind assertion adalah zero width assertion yang mana ianya bermaksud tidak memakan aksara dalam assertion yang dilakukan olehnya.
 
Contoh:
Regex:/a(?:b)/

Subjek: ab

-Tentukan samaada 'a' diikuti oleh 'b' tanpa memasukkan 'b' kedalam kesuluruhan padanan (result) - result adalah 'a' dan kedudukan semasa adalah di 'a'

 

 

Cara regex membuat assertion
Mari kita lihat bagaimana regex membuat padanan menggunakan regex dan teks dibawah
 

Contoh 1:
Regex : (?<=k)u
Teks : buku
http://regexr.com/?2vcbv]http://regexr.com/?2vcbv
 
Disebabkan ini adalah Lookbehind assertion, regex engine akan terus bergerak ke token u dan menyebabkan ianya bergerak kedalam teks sehingga ia menjumpai aksara u.Posisi sekarang adalah u yang pertama.Jadi regex engine akan cuba membuat assertion menggunakan token Lookbehind yg dilangkau tadi (?<=k).Disebabkan ini adalah Lookbehind assertion, regex engine akan undur satu tapak dan membuat assertion.Jadi kedudukan sekarang adalah b.Assertion (?<=k) dilakukan keatas b.Adakah aksara pada kedudukan ini ( B) adalah k.Assertion gagal kerana aksar pada kedudukan ini adalah b.Disebabkan regex gagal membuat padanan, ia bergerak ke u yang seterusnya.Posisi sekarang adalah u yang kedua.Disebabkan ini adalah Lookbehind assertion, regex engine akan undur satu tapak dan membuat assertion.Jadi kedudukan sekarang adalah k.Assertion (?&lt;=k) dilakukan keatas k.Adakah aksara pada kedudukan ini (k) adalah k. Assertion berjaya.u dipulangkan sebagai result terakhir tanpa memasukkan sekali assertion yg dilakukan olehnya(k).
 
 
Contoh 2:
Regex: u(?=a)h
Teks: buah
http://regexr.com/?2vcc2
 
Token pertama dalam regex adalah u, menyebakan regex akan bergerak ke dalam teks sehingga ia menjumpai aksara u.Regex menjumpai u pada kedudukan kedua.Token seterusnya didalm regex adalah Lookahead assertion menyebabkan regex engine bergerak satu tapak kedepan dan cuba untuk membuat assertion.Kedudukan sekarang adalah a.Assertion (?=a) dilakukan ke atas a.Assertion berjaya.Disebabkan ada lagi token didalam regex iaitu h, regex akan cuba membuat padanan pada kedudukan lokasi semasa.Ingat, Lookahead/Lookbehind assertion adalah zero width asertion, jadi ianya tidak memakan aksara.Jadi apabila assertion (?=a) dilakukan ke atas a dan berjaya, kedudukan semasa bukan di a, tetapi tetap di u.Ini kerana assertion adalah zero width assertion, selepas berjaya dalam assertion, regex akan kembali kepada kedudukan asal sebelum ia membuat assertion iaitu di kedudukan u.Jadi regex cuba membuat padanan token h keatas  a.Padanan tidak dapat dibuat.Regex engine gagal secara kesuluruhan.Tiada result yang dipulangkan
 
 
Contoh 3:
Regex : .+$(?<!\.php|\.html)
Teks : index.php - fail
Teks : index.asp - success (pulangkan padanan iaitu index.asp)
Teks : index.jsp - success (pulangkan padanan iaitu index.asp)
Teks : index.html - fail
http://regexr.com/?2vcbm
 
 
Contoh 4:
Regex: \w+(?=@gmail)
Teks : [email protected] - success (pulangkan padanan iaitu slier)
Teks: [email protected] - success (pulangkan padanan iaitu abu)
Teks: [email protected] - fail
Teks: [email protected] - fail
http://regexr.com/?2vcc5

//todo reediting due to forum eror
Edited by slier

Share this post


Link to post
Share on other sites

Part 10 - Conditional Statement

Q : So apa itu conditional statement didalam regex?
A : Conditional statement merupakan cara untuk membuat perbandingan..Sama saja seperti if/else dalam bahasa pengaturcaraan yg anda gunakan

Cara Penggunaan:

(?if then | else)

Conditional statement memerlukan kurungan () yang mana didalam kurungan tersebut ianya perlu diikuti dengan segera (tidak boleh diahului oleh aksara lain) oleh tanda soal ? dan kemudian dikuti dengan bahagian if (merupakan bahagian perbandingan).Kemudian diikuti oleh bahagian then (bahagian yg cuba dipadankan oleh enjin regex jika bahagian if memberikan nilai tue)..Ianya boleh disusuli dengan palang tegak (vertical bar |) dan bahagian else(bahagian yg cuba dipadankan oleh enjin regex jika bahagian if memberikan nilai false), tetapi ianyak tidaklah wajib
 
 
Untuk bahagian  if, anda boleh menggunakan assertion lookahed ataupun lookbehind. Contoh menggunakan assertion lookahaed
 

(?(?=regex) then | else) 

 
Amaran apabila menggunakan lookaround assertion..Lookaround assertion tidak memakan aksara (consume characters).Jadi apabila anda menggunakan lookaround assertion pada bahagian if, enjin regex akan membuat padanan bahagian then atau else (bergantung pada hasil lookaround assertion) pada posisi yang sama apabila enjin regex mula memasuki bahagian if
 
 
Contoh:
Regex : (a)?b(?(1)c|d)
Teks : bd - success
Teks : abc - success
Teks : bc - failed
Teks : abd - succes (matches bd)
http://regexr.com?330b8
 
Regex (a)?b(?(1)c|d) membuat padanan keatas sucjek bd dan abc.Ianya tidak membuat padanan keatas bd tetapi membuat padanan keatas abd.Mari kita lihat bagaiman enjin regex membuat padanan
 
 
Cara regex engine membuat padanan
 
Kes1:
Subjek: bd


Apabila regex engine cuba membuat padanan pada bd, ianya gagal.Memandangkan capturing group tidak wajib(optional), enjin regex cuba mula membuat padanan pada aksara 'b'.Disebabkan kesulurhan capturing group adalah tidak wajib, group tersebut langsung tidak mengambil bahagian ketiak cubaan membuat padanan.Jadi apabila cubaan untuk merujuk kepada backreference \1 akan gagal disebabkan capturing group langsung tidak mengambil bahagian
 
Nota tentang capturing group:
Perhatikan (a)? sangat berbeza dengan (?a).
Didalam kes (a)? capturing group langsung tidak akan mengambil bahagian jika enjin regex gagal untuk membuat padanan keatas aksara 'a' dan rujukan kepada backreference tersebut akan gagal sama sekali
Didalam kes (a?) capturing group sentiasa mengambil bahagian walaupun enjin regex gagal membuat padanan keatas aksara 'a'.Capturing group mungkin menyimpan(capturing) aksara 'a' kosong(tiada apa-apa)..Rujukan keatas backreference kepada capturing group yang menyimpan kosong akan sentiasa memberikan nilai true (success)..Cubaaan padanan keatas backreference seperti ini akan sentiasa menjalankan bahagian then..jadi jika ingin membuat rujukan kepada group, sila guna (a)? daripa (a?)
 
 
Sambungan kepada regex tadi, b membuat padanan keatas b.Enjin regex sekarang cuba mendapatkan nilai dari statement conditional.Memandangkan capturing group langsung tidak mengambil bahagian, conditional statement memberikan nilai false.Jadi bahagian else cuba dipadankan oleh enjin regex.Aksara 'd' padan dengan 'd'..Jadi kesuluruhan padanan dapat dilakukan.
 
Kes2:
Subjek:abc
 
Aksara 'a' padan dengan 'a' menyebabkan capturing group mengambil bahagian.Kemudian aksara 'b' padan dengan 'b'.Enjin regex cuba mendapatkan nilai untuk statement conditional.Memandangkan capturing group mengambil bahagian, conditional statement ini memberikan nilai true dan enjin regex cuba membuat padanan pada bahain then.Aksara 'c' padan 'c'.Keseluruhan padanan berjaya dilakukan.
 
Kes3:
Subjek: bc
 
Memandangkan subjek 'bc' tidak bermula dengan aksara 'a', jadi capturing group langsung tidak mengambil bahagian.Aksara 'b' padan dengan 'b', enjin regex bergerak kepada bahagian conditional statement.Memandangkan capturing group langsung tidak mengambil bahagian, conditional statement ini memberikan nilai false membuatakn enjin regex cuba membuat padanan pada bahagian else.'d' tidak padan dengan 'c'.Padanan gagal.Enjin regex bermula pada aksara kedua iaitu 'c'.''c tidak padan dengan 'b'.Padanan gagal dilakukan
 
Kes4:
Subjek:abd
 
kes 4 ini agak menarik.Seperti kes kedua, capturing group mengambil bahagian kerana 'a' padan dengan 'a'.'b' padan dengan 'b'.Enjin regex memasuki bahagian conditional statement.Memandangkan capturing group mengambil bahagian, condtional statement memberikan nilai true, dan enjin regex cuba membuat padanan bahagian then.'c' tidak padan dengan 'd'.Padanan gagal dilakukan.Perhatikan bahaian else tidak dijalankan pada waktu ini.Ini kerana capturing group mengambil bahagian, jadi hanya bahagain then yg dijalankan.
 
Walaubagaimanapun enjin regex belum lagi give up.Ianya akan memulakan proses pemadanan pada aksara yang kedua..Perhatian.setiap kali proses pemadanan dilakukan, enjin regex membuat padanan pada aksara yg pertama.Jikalau gagal untuk membuat kesulurhan pemadanan (overall matches), enjin regex akan memulakan semula proses pemadanan pada aksara yang kedua..
 
Bermula pada aksara yang kedua, a tidak padan dengan 'b'.Memandangkan ujian ini tidak wajib (optional), regex tidaklah gagal.Capturing group langsung tidak mengambil bahagian.b padan dengan 'b'.Enjin regex sekarang cuba mendapatkan nilai conditional statement.Memandangkan capturing group langsung tidak mengambil bahagian, conditional statement memberikan nilai false dan enjin regex cuba membuat padanan pada bahagian else.d padan 'd'.Kesuluruhan padanan berjaya dilakukan..
 
Jika anda tidak mahukan result seperti dalam kes4, anda cuma perlu letak anchor ^ yang memberi tahu enjin regex yang subjek merupakan permulaan aksara
 
^(a)?b(?c|d)
Subjek:abd
 
a padan 'a'.b padan 'b'.Capturing group mengambil bahagian.Conditional statement memberikan nilai true.Bahagian then cuba dipadankan oleh enjin regex.c tidak padan 'd'.Enjin regex cuba mula membuat padanan semula bermula pada aksara 'b'.Memandangkan kita menggunakan anchor ^, enjin regex membuat pemantauan adakah b merupakan permulaan aksara.Jadi keseluruhan padanan gagal dilakukan.

//todo editing
Edited by slier

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...