PHP เบื้องต้น > การควบคุมข้อความและนิพจน์ปกติี่
นิพจน์ปกติ
PHP สนับสนุนไวยากรณ์นิพจน์ปกติ (Regular Expression) 2 รูปแบบ คือ POSIX และ Perl รูปแบบ POSIX ของนิพจน์ปกติ ได้รับการคอมไพล์ไปยัง PHP ตามค่าเริ่มต้น แต่สามารถใช้รูปแบบ Perl โดยการคอมไพล์ในไลบรารี PCRE (Perl - Compatible Regular Expression) ในบทเรียนนี้จะกล่าวถึงรูปแบบ POSIX ส่วนรูปแบบ Perl หรือการเรียนรู้เกี่ยวกับ PCRE สามารถอ่านได้จากคู่มือบนเว็บที่ http://au3.php.net/manual/en/ref.pcre.php
การใช้ฟังก์ชันข้อความมีความจำกัดในค้นหา ถ้าต้องทำการจับคู่ซับซ้อนควรใช้นิพจน์ปกติที่มีประสิทธิภาพดีกว่า นิพจน์ปกติเรียนรู้ได้ลำบากในตอนต้นแต่สามารถใช้ประโยชน์ได้มาก
เบื้องต้น
นิพจน์ปกติเป็นวิธีการของการอธิบายแบบแผนข้อความ การเปรียบเทียบกับนิพจน์ปกติเป็นการประมวลของ engine กับนิพจน์นั้น ตัวอย่าง การมองหาหมายเลขโทรศัพท์สามารถสร้างนิพจน์ของหมายเลขโทรศัพท์ นอกจากมองหาตัวเลข 0-9 แล้ว ยังควรพิจารณาเครื่องหมายขีดแบ่งชุดตัวเลข เช่น ขีดแบ่งระหว่างตำแหน่งที่ 5 กับ 6
การจับคู่นิพจน์ปกติใน PHP ทำได้มากกว่าฟังก์ชันข้อความ เช่น strstr () จับคู่แทนที่การเปรียบเทียบเท่ากันทีละค่า
ตัวอักษรพิเศษสามารถใช้ระบุ meta_meaning เพื่อเพิ่มการจับคู่ตัวอักษรอย่างละเอียด ตัวอย่าง ตัวอักษรพิเศษสามารถระบุถึงแบบต้องปรากฏที่จุดเริ่มต้นหรือสิ้นสุดข้อความ ส่วนของแบบสามารถซ้ำได้หรือตัวอักษรนั้นในแบบต้องเป็นประเภทเฉพาะ รวมถึงสามารถจับคู่การปรากฏตามตัวอักษรของตัวอักษรเฉพาะ
Character Class
การใช้ชุดตัวอักษรทำให้นิพจน์ปกติมีความสามารถมากกว่านิพจน์จับคู่ละเอียด ชุดตัวอักษรสามารถใช้จับคู่ตัวอักษรต่างๆ ของประเภทเฉพาะได้แก่ ชนิดของ wildcard
สิ่งแรก , จุลภาค เป็น wildcard สำหรับตัวอักษรเดียว ยกเว้น บรรทัดใหม่ "\n" ตัวอย่าง นิพจน์ปกติ
,at
จับคู่ได้กับข้อความ "cat", "sat" และ "mat"
wildcard ชนิดนี้มักจะใช้กับการจับคู่ชื่อไฟล์ในระบบปฏิบัติการ
การระบุทำได้มากขึ้นกับประเภทตัวอักษรด้วยนิพจน์ปกติตามความต้องการและสามารถระบุเป็นชุดที่ตัวอักษรเป็นส่วนหนึ่ง ตัวอย่างก่อน นิพจน์ปกติจับคู่ "cat" และ "mat" รวมถึง "#at" ถ้าต้องการจำกัดตัวอักษรให้อยู่ระหว่าง a ถึง z สามารถระบุได้ดังนี้
[a - z]
สิ่งที่หุ้มอยู่ภายในวงเล็บสี่เหลี่ยม [ ] คือ class และตัวอักษรคือ ชุดตัวอักษรที่ต้องอยู่ภายในกลุ่มนี้
หมายเหตุ นิพจน์ในวงเล็บสี่เหลี่ยมจับคู่ตัวอักษรเพียงตัวเดียว
ตัวอย่าง กำหนดรายการตัวอักษร
[aeiou]
รวมถึงสามารถกำหนดเป็นช่วงด้วยการใช้ขีด (hyphen) หรือชุดช่วง
[a-zA-Z]
ชุดของช่วงนี้ใช้สำหรับตัวอักษรไม่ได้เป็นสมาชิกของชุด เช่น
[^a-z]
จับคู่ตัวอักษรที่ไม่ได้อยู่ในช่วง a ถึง z สัญลักษณ์ caret (^) หมายถึง ไม่ เมื่อวางอยู่ภายในวงเล็บสี่เหลี่ยม และมีอีกความหมาย หรือ ใช้ภายนอกวงเล็บสี่เหลี่ยม
นอกจากการระบุรายการชุดและช่วงแล้ว character classมาตรฐานที่สามารถใช้ในนิพจน์ปกติได้รับการแสดงในตาราง 1.5.3
ตาราง 1.5.3 character class สำหรับใช้ในนิพจน์ปกติ POSIX
Class |
การจับคู่ |
[[:alnum:]] |
ตัวอักษร alphanumeric |
[[:alpha:]] |
ตัวอักษร alphabetic |
[[:lower:]] |
ตัวพิมพ์เล็ก |
[[:upper:]] |
ตัวพิมพ์ใหญ่ |
[[:aigit:]] |
เลขฐานสิบ |
[[:xdigit:]] |
เลขฐานสิบหก |
[[:punct:]] |
เว้นวรรค punctuation |
[[:blank:]] |
tab และ space |
[[:space:]] |
ตัวอักษร whitespace |
[[:cntrl:]] |
ตัวอักษรควบคุม |
[[:print:]] |
ตัวอักษรพิมพ์ได้ทั้งหมด |
[[:graph:]] |
ตัวอักษรพิมพ์ได้ทั้งหมด ยกเว้น space |
การซ้ำ
ตามปกติ มักมีความต้องการระบุถึงการปรากฏหลายครั้งของข้อความเฉพาะหรือ character class การนำเสนอนี้สามารถใช้ 2 ตัวอักษรพิเศษในนิพจน์ปกติ สัญลักษณ์ * หมายความว่า แบบนั้นสามารถทำซ้ำ ศูนย์ครั้งหรือมากกว่า และสัญลักษณ์ + หมายความว่าแบบนั้นสามารถทำซ้ำ 1 ครั้ง หรือมากกว่า สัญลักษณ์ที่ต้องปรากฏโดยตรงหลังจากส่วนของนิพจน์ที่ประยุกต์ ตัวอย่างเช่น
[[:alnum:]]
หมายความว่า "อย่างน้อย 1 ตัวอักษร alphanumeric"
นิพจน์ย่อย
การแบ่งนิพจน์เป็นนิพจน์ย่อยสามารถใช้ประโยชน์ ตัวอย่าง "แสดงอย่างน้อย 1 ข้อความของข้อความเหล่านี้ตามด้วยหนึ่งในนั้น" การทำสิ่งนี้ด้วยการใช้วงเล็บเหมือนกับการใช้นิพจน์เลขคณิต เช่น
(very) * large
จับคู่ได้กับ "large", "very large", "very very large" และอื่นๆ
การนับนิพจน์ย่อยสามารถระบุจำนวนครั้ง ให้ทำซ้ำ สามารถใช้นิพจน์ตัวเลขในวงเล็บปีกกา ( { } ) สามารถแสดงตัวเลขการซ้ำ ( { 3 } หมายความว่า ซ้ำ 3 ครั้ง ) ช่วงการซ้ำ ( { 2,4 } หมายความว่า จาก 2 ถึง 4 ครั้ง หรือ ช่องท้ายการซ้ำเปิด ( { 2,} หมายความว่าอย่างน้อย 2 ครั้ง ตัวอย่างเช่น
(very) {1,3}
จับคู่ "very", "very very" และ "very very very"
ข้อความที่มีการสะกดซ้ำ ตัวอย่าง doomed, domed, dmed, doooomed สามารถเขียนนิพจน์ค้นหาตัวอักษรซ้ำได้
d{1,2}ed
จับคู่ได้กับ doomed และ domed
d{1, }ed
doomed, domed, และ doooomed
ระบุจุดเริ่มต้นหรือสิ้นสุดของข้อความ
นิพจน์ย่อยสามารถระบุการปรากฏจุดเริ่มต้น สิ้นสุดหรือทั้งคู่ การระบุนี้มีประโยชน์เล็กน้อย เมื่อต้องการทำให้มั่นใจว่าค้นหาเฉพาะพจน์และไม่มีสิ่งใดปรากฏในข้อความ
สัญลักษณ์ caret (^) ได้รับการใช้ที่จุดเริ่มต้นของนิพจน์ปกติเพื่อแสดงการปรากฏที่จุดเริ่มต้นของการค้นหาข้อความ และ $ ได้รับการใช้ที่จุดสิ้นสุดของนิพจน์ปกติ เพื่อแสดงการปรากฏที่จุดสิ้นสุด
ตัวอย่าง การจับคู่ chaiwat ที่จุดเริ่มต้นข้อความ
^chaiwat
การจับคู่ com ที่ท้ายข้อความ
com$
ตัวอย่างสุดท้าย การจับคู่กับตัวอักษรเดียวจาก a ถึง z ในข้อความ
^[a-z]$
Branch
การแสดงตัวเลือกในนิพจน์ปกติสามารถใช้ vertical pipe ( | ) ตัวอย่างเช่น ถ้าต้องการค้นหา com, edu หรือ net สามารถใช้นิพจน์นี้
(com) | (edu) | (net)
ตัวอักษรพิเศษ
ถ้าต้องการจับคู่ตัวอักษรพิเศษ เช่น . { หรือ $ ต้องวาง slash ( \ ) ข้างหน้า ถ้าต้องการแสดง slash ต้องแทนที่ด้วย 2 slash ( \\ )
การสรุปตัวอักษรพิเศษทั้งหมดได้แสดงในตาราง 1.5.3 และ ตาราง 1.5.4 โดยตาราง 1.5.3 แสดงความหมายตัวอักษรพิเศษภายนอกวงเล็บสี่เหลี่ยม และ ตาราง 1.5.4 แสดงความหมายเมื่อใช้ภายในวงเล็บสี่เหลี่ยม
ตาราง 1.5.4 สรุปการใช้ตัวอักษรพิเศษในนิพจน์ปกติ POSIX ภายนอกวงเล็บสี่เหลี่ยม
ตัวอักษร |
ความหมาย |
\ |
ตัวอักษร escape |
^ |
การจับคู่ที่จุดเริ่มต้นของข้อความ |
$ |
การจับคู่ที่จุดสิ้นสุดของข้อความ |
. |
การจับคู่ตัวอักษรต่างๆ ยกเว้น บรรทัดใหม่ (\n) |
/ |
เริ่มต้น branch ทางเลือก (อ่านว่า OR) |
( |
เริ่มต้นแบบย่อย |
) |
สิ้นสุดแบบย่อย |
* |
ซ้ำ 0 หรือ หลายครั้ง |
+ |
ซ้ำ 1 หรือ หลายครั้ง |
{ |
เริ่มต้น min/max quantifier |
} |
สิ้นสุด min/max quantifier |
ตาราง 1.5.5 สรุปการใช้ตัวอักษรพิเศษในนิพจน์ปกติ POSIX ภายในวงเล็บสี่เหลี่ยม
ตัวอักษร |
ความหมาย |
\ |
ตัวอักษร escape |
^ |
ไม่ เฉพาะการใช้ในตำแหน่งเริ่มต้น |
- |
ใช้ช่องตัวอักษรที่ระบุ |
วิธีการเขียนนิพจน์ปกติ
วิธีการเขียนสามารถใช้สัญลักษณ์ เช่น ".*" หมายความว่า สามารถจับคู่กับตัวอักษรใดๆได้ ตัวอย่าง "*ไก่" จะครอบคลุมถึง "บ้านของฉันเลี้ยงไก่"
ตัวอย่าง IP address ที่มีรูปแบบ aaa.bbb.ccc.ddd สามารถเขียนเป็น
[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}
{1,3} หมายถึงมีได้ 1 ถึง 3 ตำแหน่ง เนื่องจาก IP address มีหลายรูปแบบหมายเลข เช่น
5.2.7.8
192.152.0.5
255.255.205.14
|