Regular Expression
หรือ บางที่เรียกสั้นๆว่า regex คือ แบบ หรือ รูปแบบ ที่สามารถจับคู่ กับบางส่วนหรือทั้งหมดของข้อความที่เราสนใจ ตัวอย่างเช่น ถ้าเรามีข้อความ "711 Seven" ข้อความนี้ เราสามารถบอกได้ไหมครับว่ารูปแบบของข้อความนี้คืออะไร เรามาดูตัวอย่างรูปแบบที่น่าจะเป็นไปได้
รูปแบบที่ 1: "711 Seven" กล่าวได้ว่าเป็นรูปแบบตรงตัวเลย
ข้อความนี้เริ่มต้นด้วยตัวเลข 3 ตัวคือ 711 จากนั้นตามด้วยเว้นวรรคและตามด้วยคำว่า Seven ซึ่งถ้าเราต้องการจับคู่ เราก็สามารถกำหนดรูปแบบให้เหมือนกันเป๊ะ กับรูปแบบที่เราต้องการ
เราลองมาดูตัวอย่าง code python ที่ใช้
{syntaxhighlighter SPEC}
D:\wpatrProject>ipy
IronPython 2.6.1 (2.6.10920.0) on .NET 4.0.30319.235
Type "help", "copyright", "credits" or "license" for more information.
import re #นำ module re คือ regular expression module มาใช้
pat = '711 Seven' #รูปแบบที่ต้องการใส่ไว้ในตัวแปร pat
myinput = "711 Seven Ho He Ho 534 Seven and Chiyo 711 Seven"
re.findall(pat,myinput)
['711 Seven', '711 Seven']
type(re.findall(pat3,myinput))
<type 'list'>
{/syntaxhighlighter}
method findall คือ หาข้อมูลที่ตรงกับรูปแบบที่ต้องการ แล้ว return ผลลัพธ์ ออกมาเป็น list
รูปแบบที่ 2: คือ ตัวเลข ช่องว่าง แล้วตามด้วยข้อความ
ใน regex ตัวเลขตัวเดียวจะใช้รูปแบบ \d มองว่า มันเป็น 1 digit เช่น 5
ตัวเลขอย่างน้อยหนึ่งตัวใช้รูปแบบ \d+ เช่น 523
และสุดท้าย \d. โดย pattern นี้จะมองตัวแรกเป็นตัวเลขหนึ่งตัวส่วนตัวที่สองเป็นอะไรก็ได้ที่ไม่ใช้\n หรือ new line
{syntaxhighlighter SPEC}
myinput = "711 Seven Ho He Ho 534 Seven and Chiyo 711 Seven"
pat4 = '\d'
re.findall(pat4,myinput)
['7', '1', '1', '5', '3', '4', '7', '1', '1']
pat6 ='\d+'
re.findall(pat6,myinput)
['711', '534', '711']
pat2 = r'\d+\sSeven'
re.findall(pat2,myinput)
['711 Seven', '534 Seven', '711 Seven']
e = '\d.'
myinput2 = "711 Seven Ho He Ho 534 Seven and Chiyo 756998.11 Seven"
re.findall(e,myinput2) # Test
['71', '1 ', '53', '4 ', '75', '69', '98', '11']
#ตัว pattern \d. จะวิ่งเปรียบเทียบกับ myinput2 ไปเรื่อยๆ เริ่มตั้งแต่ 71 1\s se ve n\s จนถึง en ตัวสุดท้าย ถ้า match ก็จะนำมาเก็บลง list ที่เป็นผลลัพธ์แล้วนำมาแสดง
myinput2 = "711 Seven Ho He Ho 534 Seven and Chiyo 75694.11 Seven"
re.findall(e,myinput2) # Test
['71', '1 ', '53', '4 ', '75', '69', '4.', '11']
myinput2 = "711 Seven Ho He Ho 534 Seven and Chiyo 75699g.11 Seven"
re.findall(e,myinput2) # Test
['71', '1 ', '53', '4 ', '75', '69', '9g', '11']
myinput2 = "711 Seven Ho He Ho 534 Seven and Chiyo 75699g.1\n Seven"
re.findall(e,myinput2) # Test
['71', '1 ', '53', '4 ', '75', '69', '9g']
myinput2 = "711 Seven Ho He Ho 534 Seven and Chiyo 75699g.1 Seven"
re.findall(e,myinput2) # Test
['71', '1 ', '53', '4 ', '75', '69', '9g', '1 ']
{/syntaxhighlighter}
จาก รูปแบบ \d. จะได้ ผลลัพธ์แค่ 2 ตัว คือขึ้นต้นด้วยตัวเลข และ อะไรก็ได้ที่ไม่ใช้ การขึ้นบรรทัดใหม่ (\n)
จะเห็นจากตัวอย่าง ตัวเลข '1 ' นั่นคือ เลข 1 ตามด้วย space ซึ่ง space นั้น regex มองว่ามันคือ \s
อันนี้น่าจะเป็น Tutorial
PaPaSEK Thu, 07/07/2011 - 09:08
อันนี้น่าจะเป็น Tutorial มากกว่าข่าวนะครับ
ผมว่าน่าจะหาที่โพสท์ที่เกี่ยวข้องไปเลย เช่นที่ Codenone ครับ (ยังอยู่มั้ย?)
โพสที่ Blognone ก็ได้ครับ
lew Thu, 07/07/2011 - 12:10
โพสที่ Blognone ก็ได้ครับ แต่อาจจะต้องทำ syntax highlight ให้เรียบร้อย ทำ formatting ให้ถูกต้องครับ
แล้วควรจะโพสท์ในส่วนไหนครับ
PaPaSEK Thu, 07/07/2011 - 13:25
In reply to โพสที่ Blognone ก็ได้ครับ by lew
แล้วควรจะโพสท์ในส่วนไหนครับ แล้วจะได้ขึ้นหน้าหนึ่งมั้ย
น่าจะที่โค้ดโนนฟอรัมนะครับ ht
tanersirakorn Sat, 09/07/2011 - 20:52
In reply to แล้วควรจะโพสท์ในส่วนไหนครับ by PaPaSEK
น่าจะที่โค้ดโนนฟอรัมนะครับ
http://www.blognone.com/forum/codenone
ขอบคุณมากครับ
GuBaRaK Fri, 08/07/2011 - 00:29
ขอบคุณมากครับ อยากให้มีแบบนี้เยอะๆ อ่านง่ายดีครับ ขอบคุณมากนะครับ
ขอบคุณครับ เดี๋ยว จะลองดู
SitP Fri, 08/07/2011 - 14:29
ขอบคุณครับ เดี๋ยว จะลองดู นะครับ
Python เขียน Regex แบบ Perl
EThaiZone Sat, 09/07/2011 - 11:59
Python เขียน Regex แบบ Perl ได้เปล่าครับ? ผมไม่เห็นมี Delimiter แบบของ Perl เลย ผมว่าตามตัวอย่างน่าเป็นแบบ Posix
ผมยังไม่เคยศึกษา Python นะ แต่ผมว่า Regex เขียนแบบ Perl มันดีกว่านะ
ปล. ผมว่าไม่น่าขึ้นหน้าหนึ่งนะ Blognone เว็บข่าวนิครับ ไม่ใช่เว็บรวม Tutorial นะ