ข้อความต้นฉบับภาษาอังกฤษมาจาก นิตยสาร Smashing แปลโดย Benhuoer โปรดระบุแหล่งที่มาเมื่อพิมพ์ซ้ำ
นิพจน์ทั่วไป (Regular Expression, abbr. regex) มีประสิทธิภาพและสามารถใช้เพื่อค้นหาข้อมูลที่ต้องการในสตริงอักขระขนาดใหญ่ ใช้นิพจน์โครงสร้างอักขระทั่วไปในการทำงาน ขออภัย นิพจน์ทั่วไปแบบธรรมดาไม่มีประสิทธิภาพเพียงพอสำหรับแอปพลิเคชันขั้นสูงบางแอปพลิเคชัน หากโครงสร้างการกรองซับซ้อนมากขึ้น คุณอาจจำเป็นต้องใช้นิพจน์ทั่วไปขั้นสูง
บทความนี้จะแนะนำคุณเกี่ยวกับเทคนิคขั้นสูงของนิพจน์ทั่วไป เราได้คัดกรองแนวคิดที่ใช้กันทั่วไปแปดแนวคิดและวิเคราะห์พร้อมตัวอย่าง แต่ละตัวอย่างเป็นวิธีการเขียนที่เรียบง่ายเพื่อให้ตรงตามข้อกำหนดที่ซับซ้อนบางประการ หากคุณยังคงขาดความเข้าใจเกี่ยวกับแนวคิดพื้นฐานของการทำให้เป็นมาตรฐาน โปรดอ่านบทความนี้ บทช่วยสอนนี้ หรือรายการ Wiki ก่อน
ไวยากรณ์ปกติที่นี่เหมาะสำหรับ PHP และเข้ากันได้กับ Perl
1. ความโลภ/ความเกียจคร้าน
ผู้ปฏิบัติงานปกติทั้งหมดที่สามารถผ่านการรับรองได้หลายครั้งนั้นมีความโลภ จับคู่สตริงเป้าหมายให้ได้มากที่สุดเท่าที่จะเป็นไปได้ ซึ่งหมายความว่าผลการจับคู่จะยาวนานที่สุด น่าเสียดายที่แนวทางนี้ไม่ใช่สิ่งที่เราต้องการเสมอไป ดังนั้นเราจึงเพิ่มคุณสมบัติ "ขี้เกียจ" เพื่อแก้ไขปัญหา การเพิ่ม "?" หลังจากตัวดำเนินการโลภแต่ละตัวจะทำให้นิพจน์ตรงกับความยาวที่สั้นที่สุดเท่านั้น นอกจากนี้ ตัวแก้ไข "U" ยังขี้เกียจโอเปอเรเตอร์ที่สามารถผ่านการรับรองได้หลายครั้งอีกด้วย การทำความเข้าใจความแตกต่างระหว่างความโลภและขี้เกียจเป็นพื้นฐานสำหรับการใช้นิพจน์ทั่วไปขั้นสูง
ผู้ประกอบการโลภ
ตัวดำเนินการ * จับคู่นิพจน์ก่อนหน้าเป็นศูนย์หรือมากกว่าครั้ง มันเป็นผู้ประกอบการที่โลภ โปรดดูตัวอย่างต่อไปนี้:
preg_match( '/<h1>.*< /h1>/', '</h1><h1>นี่คือชื่อ</h1>
<h1>นี่เป็นอีกอันหนึ่ง </h1>', $ตรงกัน );
จุด (.) สามารถแทนอักขระใดๆ ก็ได้ ยกเว้นอักขระขึ้นบรรทัดใหม่ นิพจน์ทั่วไปข้างต้นตรงกับแท็ก h1 และทุกอย่างภายในแท็ก ใช้จุด (.) และเครื่องหมายดอกจัน (*) เพื่อจับคู่ทุกสิ่งภายในแท็ก ผลการจับคู่มีดังนี้:
<h1>นี่คือชื่อ </h1>
<h1>นี่เป็นอีกอันหนึ่ง </h1>
สตริงทั้งหมดจะถูกส่งกลับ ตัวดำเนินการ * จะจับคู่ทุกอย่างในแถว แม้แต่แท็กปิด h1 ที่อยู่ตรงกลาง เพราะมันโลภมาก การจับคู่สตริงทั้งหมดจึงสอดคล้องกับหลักการของการเพิ่มผลประโยชน์สูงสุด
ผู้ประกอบการขี้เกียจ
แก้ไขสูตรข้างต้นเล็กน้อยและเพิ่มเครื่องหมายคำถาม (?) เพื่อทำให้นิพจน์ขี้เกียจ:
/<h1>.*?< /h1>/</h1>
ด้วยวิธีนี้ มันจะรู้สึกว่าต้องจับคู่แท็กปิดท้าย h1 แรกเท่านั้นจึงจะทำงานให้เสร็จสมบูรณ์ได้
ตัวดำเนินการโลภอีกตัวที่มีคุณสมบัติคล้ายกันคือ {n,} หมายความว่ารูปแบบการจับคู่ก่อนหน้านี้ซ้ำแล้วซ้ำอีก n ครั้งหรือมากกว่านั้น หากไม่ได้เพิ่มเครื่องหมายคำถาม ระบบจะค้นหาการซ้ำให้มากที่สุดเท่าที่จะเป็นไปได้ หากเพิ่มเข้าไป ระบบจะทำซ้ำให้น้อยที่สุดเท่าที่จะเป็นไปได้ (แน่นอนว่า "ทำซ้ำ" n ครั้ง" คือค่าต่ำสุด)
#สร้างสตริง
$str = 'ฮิฮิฮิ อ๊ะ สวัสดี';
# ใช้โอเปอเรเตอร์โลภ {n,} ในการจับคู่
preg_match( '/(สวัสดี){2,}/', $str, $matches ); # การแข่งขัน[0] จะเป็น 'hihihi'
# ใช้ตัวดำเนินการลดระดับ {n,}?
preg_match( '/(สวัสดี){2,}?/', $str, $matches ); # การแข่งขัน[0] จะเป็น 'hihi'
ที่มา: งานโง่