>> รู้หมือไร่ <<
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 อยู่มากมายในท้องตลาด เช่น