regular expression

Regular Expression (Regex) คืออะไร

วันนี้มาพูดกันถึงเรื่อง Regular Expression ต่อไปขอเรียกว่า Regex แล้วกันนะครับ ทำไมถึงมาสอนเรื่องนี้ เพราะว่าคนที่จะเขียนโปรแกรมจะต้องรู้จัก เจ้าตัวนี้ไว้เปรียบเสมือนพื้นฐานของโปรแกรมเมอร์  เพราะอะไรน่ะหรอ ? เวลาที่โปรแกรมเมอร์ต้องการตรวจจับ รูปแบบ ( pattern ) ของประโยคต่างๆได้ เอาล่ะเราไปดูกันเลยว่าทำอย่างไรบ้าง

เริ่มต้นกับ Regular Expression (Regex)

regular expression

ในที่นี้ผมจะทดลองแบบ PHP นะครับและอย่างที่กล่าวไปแล้วคุณต้องเรียนรู้ตรงจุดนี้เพราะว่ามันมีประโยชน์เกี่ยวกับการตรวจสอบข้อมูล เช่น คุณต้องการจะตรวจสอบว่า User ใส่กรอกข้อมูลเป็นตัวเลขอย่างเดียวหรือเปล่า หรือว่าต้องการที่ใส่ pattern ที่คุณต้องการเช่นให้กรอก 08 ก่อนทำนองนี้ เอาล่ะ ! ร่ายยาวมาถึงนี่แล้วคุณคงเบื่อผมว่าเราไปเจอของจริงกันดีกว่าครับเอาแบบพื้นๆเบๆ ( เบสิก ) กันก่อนเลย

<?php

$string = 'Hello World. This is an example one for Regex.';

$pattern = '#Regex#';

$match = '';

preg_match($pattern, $string , $match);

print_r($match);
?>

จะเห็นว่าในตัวแปล $pattern นั้นผมใช้ ‘#’ ในการเปิดปิด pattern ซึ่งถ้าคุณเคยเห็นหรือเคยอ่านเกี่ยวกับ Regular expression (Regex) มาบ้างจะเห็นคนส่วนใหญ่ใช้ ‘/ ( slash )’ กันเยอะซึ่งผมคิดว่ามันแล้วแต่คนที่จะใช้อะไร เพราะว่าถ้าคุณใช้ ‘/’ ในการเปิดปิด เดี๋ยวจะกล่าวถึงในหัวข้อของการใช้ ‘\’ ( back slash ) อีกทีหนึ่งครับ

[ ]

การใช้ function ของ PHP นั้นจะมีใช้กันบ่อยๆก็จะเป็น preg_match , preg_match_all , preg_replace ซึ่งจะค่อยๆไปกันทีละ step อย่าใจร้อนนะ … เอ๊ะ ! บอกอย่าใจร้อนไง ( ฮา ) โอเคไปกันต่อ สมมติว่าถ้าเราต้องหาอะไรที่มัน Advance อีกนิด โดยเราอยากหาเป็นค่าช่วงระหว่างหรือว่าเป็นแบบเป็น a หรือ b แต่อาจจะไม่ดีนะสำหรับการใช้ หรือผมจะแนะนำอีกตัวให้ดูแล้วกัน ดูตัวอย่างด้านล่างครับ

$string = 'Hello World. Hey ! I just meet you';

$pattern = '#He[l-y]#';

$match = '';

preg_match($pattern, $string , $match);

print_r($match);

อ้าวทำไมเป็นอย่างนี้ล่ะ บอกว่าเป็นหรือแล้วใส่ [ly] มันก็น่าจะจับมา 2 ตัวคือ Hel หรือ Hey แต่ทำไมคำตอบถึงออกมาเป็นแค่ Hel อันเดียวแล้วถ้าเราจะให้จับมาทั้งสองตัวจะทำอย่างไร มันจึงเกิด function preg_match_all ยังไงล่ะครับ คราวนี้เราก็จะสามารถเอา ‘ทุกตัว’ ที่ตรงกับที่เราต้องการได้แล้ว จากตัวอย่างที่แล้วถ้าคุณลองเปลี่ยน function preg_match เป็น preg_match_all ก็จะได้แล้วครับ

นอกจากใช้เป็น เงื่อนไขรูปแบบ ‘หรือ’ แบบง่ายๆแล้วยังใช้เป็นช่วงระหว่างได้ เช่นเราต้องการ ให้ User กรอกข้อมูลที่เป็นตัวเลข  เท่านั้นถ้า User ใส่ข้อมูลอะไรที่มีตัวเลข ก็จะตรวจเจอ

$string = 'Hello World. Hey ! I just meet you. Today is 30/6/2555';

$pattern = '#[0-9]#';

$match = '';

preg_match_all($pattern, $string , $match);

print_r($match);

จะเห็นว่าเราจะได้ชุดตัวเลขทุกตัวซึ่งในความเป็นจริงเราก็ไม่ได้อยากได้เยอะขนาดนี้ บางทีเราอาจจะอยากได้ ‘ตัวเลขที่มี 2 ตัวขึ้นไป’ เราจะต้องใช้อีกเครื่องมือหนึ่งมาเข้ามาช่วยนั่นก็คือ

{n,m}

  • n คือ ค่าที่น้อยที่สุดที่ต้องการ
  • m คือ ค่าที่มากที่สุดที่ต้องการ

ถ้าคุณไม่ใช่ค่า m มันจะเหมือนกับเขียนในรูปแบบนี้ { n , } มันแปลว่าเอาค่าที่ต่ำสุด n และมากขึ้นไปเท่าไรก็ได้ แต่ถ้าหากเราใส่แค่ว่า { n } อย่างนี้จะเป็นการบอกว่าเอาแค่ทีละ 2 ตัวเท่านั้นไม่มีน้อยหรือมากไปกว่านี้ เพื่อความเข้าใจเรามาดูตัวอย่างกันเลยดีกว่า

$string = 'Hello World. Hey ! I just meet you. Today is 30/6/2555';

$pattern = '#[0-9]{2}#';
$pattern1 = '#[0-9]{2,}#';

$match = '';

preg_match_all($pattern, $string , $match);
preg_match_all($pattern1, $string , $match1);

print_r($match);
//output : Array ( [0] =&gt; Array ( [0] =&gt; 30 [1] =&gt; 25 [2] =&gt; 55 ) ) 

print_r($match1);
//output : Array ( [0] =&gt; Array ( [0] =&gt; 30 [1] =&gt; 2555 ) )

ในตัวแปร $match เราจะได้ตัวเลขที่ เป็น 2 ตัวเท่านั้น แต่อีกตัวอย่างที่เราเพิ่มขึ้นนั้นจะได้ชุดตัวเลข เลยที่ เป็นจำนวน 2 ตัวขึ้นไป ดังจะเห็นได้จากโค้ดแล้วตัวอย่างนี้มีประโยชน์อย่างไร มีประโยชน์เช่น เมื่อคุณต้องการให้ User กรอกตัวเลขเบอร์โทรศัพท์คุณก็สามารถกำหนดได้ว่าให้กรอกเท่าไร กี่ตัว เป็นตัวเลขหรือว่าตัวอักษรด้วยหรือไม่

^

ตัวสัญลักษณ์ตัวนี้ ‘^’ หมายถึง ประโยคที่นำมาตรวจจับจะต้องมีคำที่ตามหลัง ^ เช่น ถ้าหาก User ใส่ข้อความมา ‘This is a book. This is not a pen.’ เราต้องการแค่หากมีคำว่า This ขึ้นต้นก็จะผ่านฉะนั้น code ของเราจะเป็นอย่างนี้

$string = 'This is a book. This is not a pen.';

$pattern = '%^this%';

preg_match($pattern, $subject , $match);

print_r($match);

//output : null

อ้าวทำไม output มันไม่มีล่ะ เอ่อ !! นั่นสิน่าสงสัยมะ เพราะว่าตัวที่เราหานั้นคือ this ตัวอักษร t ตัวเล็กแต่ในประโยคนั้นเป็นตัวใหญ่จึงทำให้คอมมันหาไม่เจอ แล้วสมมติว่าเราต้องการทั้งตัวใหญ่ ตัวเล็กทำยังไงล่ะ ?? คราวนี้ผมจะให้เครื่องมืออีกหนึ่งตัวเป็นเสมือนตัว support ถ้าเรามองในพวกเกมส์ ที่จะช่วยเหลือเราพวกเรื่องเล็กน้อยเหล่านี้ในทาง Regex เราเรียกว่า Modifiers เรามาดูกันที่ใช้บ่อยๆแล้วกันจากตัวอย่างข้างบนถ้าเราต้องการหา ไม่ว่าจะตัวใหญ่หรือเล็กให้เจอล่ะก็ ให้เราใส่ตัว ‘i’ ตามหลังตัวปิดเปิด pattern ดังตัวอย่างข้างล่าง

$string = 'This is a book. This is not a pen.';

$pattern = '%^this%i';

preg_match($pattern, $string , $match);

print_r($match);

//output : Array ( [0] =&gt; This )

คราวนี้เราก็จะเจอคำว่า This ที่เราต้องการไม่ว่าจะตัวเล็กตัวใหญ่ตรงไหนก็ตามก็จะตรวจเจอ เช่น This, tHis, thIs, THIS ฯลฯ แต่ต้องเป็นคำแรกที่อยู่ขึ้นต้นประโยคนะครับเพราะอย่าลืมว่าในตัวอย่างเราใช้ ^ อยู่

บางคนสงสัยว่าแล้วภาษาไทยล่ะตรวจได้ไหม คำตอบคือ ได้ครับจากที่กล่าวมาเราจำเป็นต้องทำ 2 อย่างในการทำให้ใช้ภาษาไทยได้นั่นก็คือ

  • ต้อง save ไฟล์เป็น UTF-8
  • จะต้องใช้ modifier ตัว ‘u’ ( ตัวเล็กนะครับ )

ก็จะสามารถใช้กับภาษาไทยได้แล้ว

เอาล่ะเราไปลองตัวอย่างภาษาไทยกันบ้างดีกว่าพร้อมกับตัวช่วยในการแยกคำตัวใหม่อีกหนึ่งตัวนั้นก็คือ

$

ตัวนี้จะช่ีวยเราในเรื่องเวลาที่เราต้องการให้ตรวจสอบคำหลังสุดของข้อความ เอาล่ะเราไปดูตัวอย่างกันเลยดีกว่าครับ

$string = 'สวัสดีจ้าทุกคน วันนี้ผมจะมาเล่าเรื่อง Regex กันนะครับ ครับ ครับ ครับ';

$pattern = '%ครับ$%';

preg_match($pattern, $string , $match);

print_r($match);

//output : Array ( [0] =&gt; ครับ )

แล้วคุณจะสังเกตุว่าผมไม่ได้ใส่ modifier ตัว ‘u’ ลงไปแล้วมันก็ยังหาเจอใช่ครับหาเจอแต่ว่าผมจะให้ดูอีกตัวอย่างหนึ่งคุณจะร้องอ๋อเลยว่าทำไมผมถึงต้องใช้ u ช่วย

$string = 'สวัสดีจ้าทุกคน วันนี้ผมจะมาเล่าเรื่อง Regex ซึ่งมันอาจจะเป็นเรื่องที่ยากหรือไม่ก็ลองอ่านกันดู';

$pattern = '%จะ[เม]%';

preg_match($pattern, $string , $match);

print_r($match);

เราจะได้ค่ามาอย่างนี้เพราะว่ามันตัดคำไม่ถูกต้องอย่างที่เราตั้งใจ ในตัวอย่างข้างบนจริงๆแล้วเราจะได้คำตอบคือ ‘จะม’ เพราะว่ามันเจอคำว่า ‘จะมา’ ก่อนแต่จริงๆคำหลังก็ได้เพราะผมไม่ได้ใช้ preg_match_all นั่นเองถึงได้มาคำเดียวแล้วถ้าคุณลองใส่ตัว u ลงไปเราก็จะได้คำตอบอีกแบบ

เห็นหรือยังครับความนี้คุณสามารถเลือกคำที่ต้องการได้แหละ ง่ายใช่เปล่าฮ่าๆ เอาล่ะถ้าสมมติเราต้องการใส่ user กรอกแต่ภาษาไทยเท่านั้นทำอย่างไรล่ะ เออ … อย่างนี้ก็เคยเจอนะแบบว่าไม่ให้ใช้ภาษาอังกฤษก็ง่ายๆครับผมแนะนำให้สองแบบคือ

$string = 'สวัสดีครับทุกคน';

$string2 = 'test';

$pattern  = '%[ก-ฮ]%u';

$pattern2 = '$[ก-๙]%u';

preg_match_all($pattern,$string,$match1);
preg_match_all($pattern2,$string,$match2);
preg_match_all($pattern,$string2,$match3);

จากตัวอย่างถ้าเราทำการ print_r ($match1); นั้นเราจะไ้้ด้แต่ ตัวอักษรไทยเท่านั้น แล้วถ้าเราลองทำการดูค่าของ $match2 เราได้ตัวอักษรไทยทั้งหมดและรวมสระด้วย สุดท้ายนั้นเราจะหาไม่เจอเพราะว่าเราเอาคำว่า ‘test’ มาตรวจหา

ขอให้สนุกกับการใช้ Regular expression (Regex) นะครับความจริงแล้วยังมีลูกเล่นอีกหลายๆอย่างเช่นตรวจหา E-mail ทำอย่างไรหรือว่าชุดตัวเลข IP ทำอย่างไรแต่วันนี้เอาแค่นี้ก่อนจ้าถ้าใครอยากลองวิชาผมมีเว็บให้ลองบนเว็บได้เลยไม่ต้องทำ host รัน PHP ให้เสียเวลาแต่ใช้ modifier ‘u’ ไม่ได้นะจ๊ะหาคำไทยได้ตัดไม่ฉลาดหรอกจ้า

ร้อนวิชาจัดไป http://gskinner.com/RegExr/

แน่นอนว่าบทความนี้ยังมีต่ออีกหลายภาคแน่นอนเพราะว่าเรื่องนี้เอาไปประยุกต์ได้อีกเยอะมาก ทั้งเรื่องการทำ Bot ( อุ๊บส์ ! ) หรือหาข้อมูลจากเว็บชาวบ้าน

สรุปเรื่อง Regular expression

มันอาจจะเรียนรู้แล้วลำบากนิดหน่อย แต่อยากให้ลองฝึกเพราะว่ามันใช้ได้หลากหลายภาษาในปัจจุบัน ไว้สำหรับการจัดการพวก text file และการจัดการข้อมูลในปัจจุบัน หากจะเรียนรู้ว่าจะเอาไปใช้งานอย่างไรอยากเริ่มเรียนการทำเว็บเชิญทางนี้เลยครับ

สารบัญเริ่มต้นเขียนเว็บ

Loading

เป็นโปรแกรมเมอร์ที่ตามหาคุณค่าของชีวิตและความฝันในวัยเด็ก ชอบเล่นเกม เรียนรู้ทุกอย่าง ชอบเจอคนใหม่ๆ งานสังคมทุกชนิด ออกกำลังกายในวันว่าง อ่านหนังสือ มีเว็บรีวิวหนังสือด้วย www.readraide.in.th