173   PHP หลักการเบื้องต้นว่า regular expression ทำงานอย่างไร โดยเฉพาะเรื่อง cursor และ state

>> รู้หมือไร่ <<

Regular Expression คือภาษาสัญลักษณ์ที่ใช้ในการกำหนด "search pattern"
ซึ่งสามารถนำไปใช้ในการค้นหาข้อความหรือส่วนที่ต้องการใน string
 
คำว่า "search pattern" หรือรูปแบบในการค้นหานั้น มันก็หมายถึงเงื่อนไขในการค้นหา

ยกตัวอย่างง่ายๆ

มั่นใจว่าทุกคนคงเคยใช้ฟังก์ชั่น str_replace() ที่ใช้การแทนที่สตริงอย่างง่ายกันมาบ้างแล้ว
 
$subject = "It's you who is my enemy.";
echo str_replace('you', 'me', $subject); 
// แทนที่ you ด้วย me
 
แม้ str_replace() จะไม่รองรับ regular expression แต่เราสามารถมองคำค้น 'you' เป็น
regular expression หรือชุดของเงื่อนไขได้
 
ซึ่งในการค้นหา จะต้องมี "cursor" (ตำแหน่งปัจจุบัน) ที่ใช้บอกว่ากำลังค้นหา ณ จุดไหน ไปถึงไหนแล้ว
กับ state (ตำแหน่งของเงื่อนไข) โดยในทุกๆ รอบการค้นหา
จะเพิ่ม cursor ไปเรื่อยๆ ทีละ unit ซึ่งอาจเป็น 1 byte หรือมากกว่าแล้วแต่ encoding ที่ใช้
ซึ่งถ้า cursor อยู่ท้ายสตริงที่ค้นหา ก็คือจบการทำงาน

ขั้นตอนการทำงานแบบคร่าวๆ

1. ถ้าข้อมูล ณ cursor คือ y บันทึกตำแหน่ง cursor ไว้ และเปลี่ยนเป็น state 2
2. ถ้าข้อมูล ณ cursor คือ o ให้เปลี่ยนเป็น state 3 นอกนั้นกลับไป state 1
3. ถ้าข้อมูล ณ cursor คือ u ให้เปลี่ยนเป็น state 4 นอกนั้นกลับไป state 1
4. ทำการแทนที่คำว่า 'me' ณ ตำแหน่งที่บันทึกไว้ และกลับไป state 1 ทำการค้นหาต่อไป
 
[I]t's you who is my enemy.
 cursor ไม่ใช่ y ดังนั้น state ยังคงเป็น 1

I[t]'s you who is my enemy.
 cursor ก็ยังไม่ใช่ y ดังนั้น state ยังคงเป็น 1 ไปเรื่อยๆ จนกว่า

It's [y]ou who is my enemy.
cursor คือ y เข้าเงื่อนไข บันทึกตำแหน่งไว้ state เปลี่ยนเป็น 2

It's y[o]u who is my enemy.
cursor คือ o เข้าเงื่อนไข state เปลี่ยนเป็น 3

It's yo[u] who is my enemy.
cursor คือ u เข้าเงื่อนไข state เปลี่ยนเป็น 4

It's me who is my enemy.
แทนที่ you ด้วย me และให้ cursor ไปอยู่หลัง me และเปลี่ยน state เป็น 1 ทำการค้นหาไปเรื่อยๆ จนกระทั่ง

It's me who is my enemy[.]
cursor คือ . ซึ่งไม่เข้าเงื่อนไขใดๆ แต่ก็ไม่มีข้อมูลให้ค้นหาแล้ว จึงถือว่าจบการทำงาน

ซึ่งจากตัวอย่างที่กล่าวมาเงื่อนไขของเราในแต่ละ state นั้นเป็นค่าคงที่
คือ y ก็คือ y ไม่ใช่ a ไม่ใช่ Y (ตัวพิมพ์เล็กใหญ่ก็ถือว่าต่างกัน)
แต่หากเราใช้ Regular Expression เงื่อนไขของเราจะหลายหลายขึ้น
เช่น
 
$subject = "It's you who is my enemy.";
echo preg_replace('/[yY]ou/', 'me', $subject);​
// แทนที่ you หรือ You ด้วย me
 
ตัวอย่างนี้เปลี่ยนจาก str_replace() มาเป็น preg_replace()
และคำค้นจาก 'you' มาเป็น pattern '/[yY]ou/'
 
อธิบาย pattern ที่ใช้ในตัวอย่างนี้คร่าวๆ

คือ delimiter กล่าวคือเป็นสัญลักษณ์ที่บอกว่า ต่อจากนี้คือ Regular Expression ซึ่งจะต้องปิดด้วย
สัญลักษณ์เดียวกัน

[] เรียกว่า character class ซึ่งตัวอักษรใดๆ ก็ตามที่อยู่ระหว่าง [ และ ] นั้น จะให้ความหมายว่า "หรือ"
เช่น [abc01] จะหมายถึง ตำแหน่งนี้สามารถเป็นได้ทั้ง a, b, c, 0 และ 1
ดังนั้น [yY] จะหมายความว่า y หรือ Y

ซึ่งจะได้ขั้นตอนการทำงานแบบคร่าวๆ

1. ถ้าข้อมูล ณ cursor คือ y หรือ Y บันทึกตำแหน่ง cursor ไว้ และเปลี่ยนเป็น state 2
2. ถ้าข้อมูล ณ cursor คือ o ให้เปลี่ยนเป็น state 3 นอกนั้นกลับไป state 1
3. ถ้าข้อมูล ณ cursor คือ u ให้เปลี่ยนเป็น state 4 นอกนั้นกลับไป state 1
4. ทำการแทนที่คำว่า 'me' ณ ตำแหน่งที่บันทึกไว้ และกลับไป state 1 ทำการค้นหาต่อไป
 
จะเห็นว่าความแตกต่างกับแบบ str_replace() คือ state 1 ที่ตรวจทั้ง y และ Y

ประเด็นหลักของเกร็ดความรู้นี้ ไม่ใช่การสอน Regular Expression
แต่คือการให้เข้าใจหลักการเบื้องต้นว่า Regular Expression ทำงานอย่างไร
โดยเฉพาะเรื่อง cursor และ state
ซึ่งอาจจะเปลี่ยนมุมมองของคุณที่มีต่อ Regular Expression จากเดิมที่มองเป็นโค้ดอะไรก็ไม่รู้
ให้เปลี่ยนเป็นการวิเคราะห์และจำแนกมันออกมาเป็นชุดของเงื่อนไขหรือคำสั่ง
ซึ่งจริงๆ มันก็มี tools ที่ช่วยวิเคราะห์ Regular Expression อยู่มากมายในท้องตลาด เช่น
หรือ online tool อย่าง https://regex101.com

Credit: Admin (phpinfo.in.th)
Back to Top