เพราะเนื่องจากภาษา Perl เป็นภาษาที่จัดการเกี่ยวกับระบบ Linux จึงทำให้การกำหนด expression มีลักษณะเหมือนกัน (ตามที่ได้กล่าวในบทความก่อน) ซึ่งรายละเอียดการกำหนด expression ในการค้นหาคำนั้นจะค่อย ๆ กล่าวไปที่ละลำดับเพื่อให้ผู้อ่านไม่งง และเข้าใจง่าย
ซึ่งเป็นแบบที่กำหนดง่ายสุด นั่นก็คือการกำหนดคำที่ต้องการค้นหาแบบตรงตัว ดังตัวอย่าง
$user_location = "I see thirteen black cat under a ladder.";
if ($user_location =~ /thirteen/) {
print "Eek, bad luck!\n";
}
# =~ /thirteen/ แปลว่า ในตัวแปร $user_location ต้องมีคำว่า thirteen อยู่ที่ไหนก็ได้ในนั้น
# ถ้ามี = true ไม่มี = false
การกำหนดแบบ Metacharacters พูดแบบเข้าใจง่าย ๆ ก็คือกำหนดถึงคำที่เริ่มต้น (^) กับคำที่สิ้นสุด ($) ของบรรทัดที่ค้นหานั้น ๆ
# ^ -> สตริงที่ต่อจาก ^ จะต้องมีในจุดเริ่มต้นของ String ที่ค้นหา # $ -> สตริงที่อยู่ก่อน $ จะต้องมีในจุดสุดท้ายของ String ที่ค้นหา # เช่น for $line() { # if the line starts with http: and end with html if (($line =~ /^http:/) and ($line =~ /html$/)) { print $line; } }
ในรูปแบบนี้ ความหมายก็คือกำหนดการค้นหาคำที่ละเอียดกว่าเดิมนั่นแหละครับ ไม่มีคำบรรยายใด ๆ ทั้งสิ้น ลองไปดูตัวอย่างกัน
# /a.b/ # คือค้นหาคำว่า a โดย . ที่คั่นกลางจะแทนด้วยตัวอักขระอะไรก็ได้ที่อยู่ในบรรทัดเดียวกัน # แต่ต้องลงท้ายด้วย b และไม่จำเป็นต้องอยู่ท้ายประโยค # เช่น acdeb, acb, acgbz เป็นต้น # ถ้าต้องการให้ค้นหาอักขระ . ด้วยให้ใช้ /Mr\./ จะใช้ /Mr./ไม่ได้
นอกจากนี้ยังมีสัญลักษณ์อีก 3 ตัวที่เป็นตัวช่วยในการค้นหาคำ ซึ่งมีความหมายในการใช้ต่างกันเพียงนิดเดียว ดังนี้
# + -> /ab+c/ คือในประโยคนั้น ๆ จะต้องมีอักขระข้างหน้า + อย่างน้อย 1 ตัวและมีกี่ตัวก็ได้ เช่น abc, abbc, abbbbc # * -> /ab*c/ จะมีการใช้เหมือนกับ + เพียงแต่จะต่างกันตรงที่ไม่มีอักขระข้างหน้า * ก็ได้ เช่น ac, abc, abbc คือจะต้องมีอักขระข้างหน้า * อย่างน้อย 0 ตัวและมีกี่ตัวก็ได้ # ? -> /ab?c/ อักขระข้างหน้า ? จะไม่มีก็ได้หรือถ้ามี จะต้องมีแค่ 1 ตัว เช่น ac, abc
เมื่อเรารู้จักสัญลักษณ์เพิ่มเติมเรียบร้อยแล้ว เราสามารถย่อคำสั่งค้นหาคำได้สั้นลงดังนี้
for $line (<URLLIST>) {
if ($line =~ /^http:.+html$/) {
print $line;
}
}
# หมายความว่า เริ่มบรรทัดจะต้องมีคำว่า http:
# และต่อจากนั้นต้องมีอักขระอะไรก็ได้อย่างน้อย 1 ตัว
# และต้องลงท้ายสตริงด้วย html
ความหมายของ Character Classes แต่ละตัวมีความหมายแตกต่างกันไป เราลองไปดูความหมายของ Character Class เพื่อสามารถนำไปใช้ในการค้นหาคำที่ละเอียดยิ่งขึ้น
\d -> ตัวเลขตัวเดียว
\w -> ตัวอักษร ตัวเลข หรือ _ เพียงตัวเดียว
\s -> ช่องว่าง หรือแท็บ (\n, \r)
\D -> inverse ของ \d นั่นคือ อะไรก็ได้ที่ไม่ใช่ตัวเลข
\W -> inverse ของ \w นั่นคือ อะไรก็ได้ที่ไม่ใช่ letter, digit, underscored
\S -> inverse ของ \s นั่นคือ อะไรก็ได้ที่ไม่ใช่ whitespace, tab (\n, \r)
# เช่นการเช็คหมายเลขโทรศัพท์ของ USA จะมีรูปแบบ 555-1212
unless ($phone =~ /\d\d\d-\d\d\d\d/) {
print "That's not a phone number.";
}
# หรือ
unless($phone =~ /\d{3}-\d{4}/) {
print "That's not a phone number.";
}
เรายังสามารถกำหนด Character Classes เองได้ ซึ่งต้องอยู่ภายใน [] เช่น
# [aeiou]
# /b[aeiou]g/ จะ match กับ bag, beg, big, bog, bug
# และยังสามารถใช้ - เพื่อกำหนดช่วงของอักขระได้เช่น
# [a-u] ซึ่งหมายความว่าตัวอักษรตั้งแต่ a - u
# \d มีความหมายเท่ากับ [0-9]
# เช่นการค้นหาสระ aeiou อะไรก็ได้ (จะเป็น a|e|i|o|u ก็ได้) ที่ต้องมีอย่างน้อย 2 ตัว
if ($string =~ /[aeiou]{2}/) {
print "The string contains at least two vowels in a rows\n";
}
เราสามารถ invert Character classes เหล่านี้ได้โดยใส่ ^ ไว้ข้างหน้าอักขระเหล่านั้น เช่น [^aeiou] เพื่อค้นหาคำที่ไม่มีอักขระ aeiou อยู่ในนั้น และต้องระมัดระวังการใช้ ^ เพราะในบทที่แล้วจะหมายถึงจุดเริ่มต้นของสตริง แต่ในบทนี้จะเป็นการ invers Character Classes
ค่าคงที่ของ regular expression คือเป็น case-sensitive (/bob/ ไม่ match กับ /Bob/) เราสามารถใส่ flag หลัง regular expression เพื่อเปลี่ยนแปลงการกระทำของมัน (จาก case-sensitive เป็น case-insensitive) โดยใช้ Flag i เช่น
$great = "Hey everybody, it's Bob and David!";
if ($great =~ /bob/i) {
print "Hi, Bob!\n";
}
# จาก $great จะเข้าเงื่อนไขนี้ เนื่องจากใช้ flag i ที่ท้าย regular expression
จบไปอีกบทความนึง เกี่ยวกับ Expression ครับซึ่งมีประโยชน์มากในการเขียนโปรแกรม perl กับการค้นหาคำ และผมหวังว่าบทความที่ผมเขียนไปจะมีประโยชน์กับผู้อ่านทุกคนนะคร้าบบบบ......
Login
Search| ความเห็นของผู้อ่าน |
| ยังไม่มีความเห็นในบทความนี้ |
| Comment |