คุณอาจได้ยิน RegEx ย่อมาจาก Regular Expressions อาจดูน่ากลัว แต่จริงๆ ไม่ยากนักเมื่อคุ้นเคยกับรูปแบบและการสร้าง Expression จริง เมื่อคุ้นเคยกับการคิดเกี่ยวกับ Strings และข้อความแบบ Abstract มันเป็นเครื่องมือที่มีประโยชน์สำหรับแก้ปัญหาที่ต้องหา Pattern ร่วมในชุดข้อมูล
RegEx เป็นวิธี Pattern Matching: กรอง Strings หรือข้อความตาม Pattern เพื่อ Extract และ Modify ข้อความที่ต้องการ ในบทความนี้จะสอนใช้ Regular Expressions และทดสอบด้วย Ruby Methods เพื่อนำไปใช้ใน Logic โปรเจกต์
เครื่องมือที่ช่วย Visualize และเข้าใจ RegEx ได้ดีคือเว็บ Rubular กดลิงก์เพื่อทดสอบ RegEx กับข้อความที่มีอยู่ ระหว่าง Slash สองตัวมีคำว่า 'neighbor'
เชื่อหรือไม่ นี่คือ Regular Expression! คำเต็ม ประโยค ย่อหน้า ก็เป็น Regular Expression ได้ (ตราบใดอยู่ระหว่าง Slash สองตัว) Rubular จะ Highlight ทุก Instance ของ Pattern 'neighbor' ในข้อความ - รวมถึงที่เป็นส่วนของคำใหญ่กว่า! แต่คุณอาจต้องการหาอะไรที่ Abstract มากกว่าคำที่ตรงกันทุกตัว นี่คือที่มาของ Metacharacters
Metacharacters
การใช้ RegEx ท้าทายถึงนักเขียนโปรแกรมมืออาชีพ อย่าผิดหวัง
เช่นเดียวกับอะตอมที่เป็นบล็อกก่อสร้างทุกสิ่ง Metacharacters คือบล็อกก่อสร้างของ Regular Expressions เมื่อเพิ่มบน Regular Expression Pattern ทั้งหมดจะเปลี่ยน และผลลัพธ์จาก Methods ที่ใช้ก็จะต่างออกไป
ด้านล่างคือหลายวิธีปรับ Regular Expression เพื่อหา Pattern ที่เหมาะกับคุณ ไม่มีวิธีเดียวที่ ถูกต้องที่สุด สำหรับเบอร์โทร อีเมล ฯลฯ - ทุกอย่างขึ้นอยู่กับความต้องการโปรเจกต์ของคุณ
| Metacharacter | Matches | Example |
|---|---|---|
| [abc] | Character class ตรงตัวอักษรเดี่ยวที่เป็น a, b หรือ c | /[eig]/ ตรงส่วนของ neighbor, apple, หรือ gate |
| [^abc] | Negated character class ตรงทุกตัวอักษร ยกเว้น a, b, c | /[^eig]/ ตรงส่วนของ neighbor, apple, หรือ gate |
| [a-z] | Character class ตรงตัวอักษรเดี่ยวในช่วง a-z | /[e-i]/ ตรงตัวอักษรเดี่ยวในส่วนของ neighbor, apple, หรือ gate |
| [a-zA-Z] | Character class ตรงช่วงตัวอักษร a-z หรือ A-Z | /[e-i]/ ตรงตัวอักษรเดี่ยวในส่วนของ "Hi neighbor!", Grapple, หรือ gate |
| ^ | Start of line | /^Hello/ ตรงบรรทัดเริ่มด้วย 'Hello' |
| $ | End of line | /Goodbye$/ ตรงบรรทัดจบด้วย 'Goodbye' |
| \A | Start of string คล้าย '^' แต่ไม่มี multiline mode | /\Aa/ ตรง 'a' ใน apple แต่ไม่ใช่ 'a' ใน apricot เพราะไม่ใช่ต้นสตริง |
| \z | End of string คล้าย '$' แต่ไม่มี multiline mode | /\za/ ตรง 'a' ใน zebra แต่ไม่ใช่ 'a' ใน libra เพราะไม่ใช่ท้ายสตริง |
| . | Wild card Dot ตรงตัวอักษรใดๆ | /./ ตรงตัวอักษรเดี่ยวใดๆ ใน apple |
| + | ตรงหนึ่งขึ้นไปของ metacharacter ก่อนหน้า | /aa+/ ตรง 'aa', 'aaaaaaa' แต่ไม่ตรง 'a' เพราะต้องมีหนึ่งขึ้นไปของ metacharacter ก่อนหน้า (คือ a ตัวที่สอง) |
| * | ตรงศูนย์ขึ้นไปของ metacharacter ก่อนหน้า | /ab*/ ตรง 'a', 'ab', 'abbbbbb' |
| \s | Whitespace character ใดๆ | /^The\s.+s$/ ตรง The Beatles, The Rolling Stones, The Cranberries, ฯลฯ |
| \S | Non-whitespace character ใดๆ | /\S+/ ตรง The Beatles, The Rolling Stones, The Cranberries, ฯลฯ |
| \d | Digit ใดๆ | /\d+/ ตรง 22, 33333, 0, ฯลฯ |
| \D | Non-digit ใดๆ | /\D+/ ตรง 'Hello, goodbye' |
| \w | Word character ใดๆ | /ny\w*/ ตรง 'ny_152', 'nypost39', ฯลฯ |
| \W | Non-word character ใดๆ | /\W+/ ตรง ')(*&^%$' |
| a{3} | a ทั้งหมด 3 ตัว | /\d{3}-\d{3}-\d{4}/ ตรง 555-555-5555 |
| a{3,} | a 3 ตัวขึ้นไป | /[a-zA-Z0-9!#$^&*)(]{8,}/ ตรง 'xE*BqRx14B7TAQp' ⇐ ดูเหมือน Password! |
| a{3,6} | a 3 ถึง 6 ตัว | /[a-zA-Z0-9!#$^&*)(]{8,32}/ ตรง '0XX!pC3Odpu30Qc' เพราะมากกว่า 3 และน้อยกว่า 32 ตัวอักษร |
| a? | a 0 หรือ 1 ตัว | /\d?-\d{3}-\d{3}-\d{4}/ ตรงเบอร์โทรมีรหัสนานาชาติหน้าและไม่มีรหัสนานาชาติ |
การใช้ Metacharacters ดีสำหรับ Validation เมื่อผู้ใช้กรอกฟอร์มบนเว็บ ต้องการให้ข้อมูลถูกต้อง - RegEx ช่วยตรวจสอบรูปแบบที่อยู่ อีเมล เบอร์โทร ให้ถูกต้อง นำไปสู่ Database ที่จัดระเบียบดีและลดข้อผิดพลาดผู้ใช้
Methods ทดสอบ RegEx ใน Ruby
โค้ดด้านล่างใช้แยกความแตกต่างระหว่าง Scan และ Match:
#!/usr/bin/ruby
class RegexTest
def initialize(str, regex)
@str = str
@regex = regex
@result = str.scan(regex)
end
def display_details()
puts "String = #@str"
puts "regex = #@regex"
puts "result = #@result"
end
end
# Create Objects
str1 = RegexTest.new("The rain in Spain stays mainly on the plain", /\w+ain/)
str2 = RegexTest.new("In Hertford, Hereford, and Hampshire, hurricanes hardly ever happen", /H\w+/)
# Call Methods
str1.display_details()
str2.display_details()
Scan
Method Scan ใน Ruby คืน Array ของ Strings ทั้งหมดที่ตรง Regular Expression:
str1: result = ["rain", "Spain", "main", "plain"]
str2: result = ["Hertford", "Hereford", "Hampshire"]
ช่วยให้ทำอะไรก็ได้กับ Result
RegExp Match
Method Match คล้าย Scan มาก แต่หา Instance แรกที่ตรง แทนที่จะหาทั้งหมด เปลี่ยน @result = str.scan(regex) เป็น @result = str.match(regex) เพื่อดูความแตกต่าง:
str1: result = rain
str2: result = Hertford
Match คืน Object
Grep
Grep เป็น Enumerable method หา Strings ที่ตรงใน Arrays คืน Array ของ Strings ที่ตรง Regular Expression ต้องแยก String ที่ส่งเข้าเป็น Array ก่อน
เปลี่ยนบรรทัดนี้:
@result = str.match(regex)
เป็น:
@result = str.split(/\s|,/).grep(regex);

"Career Karma เข้ามาในชีวิตฉันเมื่อฉันต้องการมากที่สุด และช่วยจับคู่กับบูทแคมป์ได้เร็ว สองเดือนหลังจบ ฉันพบงานฝันที่ตรงกับคุณค่าและเป้าหมายในชีวิต!"
Venus, วิศวกรซอฟต์แวร์ที่ Rockbot
ค้นหาบูทแคมป์ของคุณ
จะได้ Result คล้าย Result แรก:
str1: result = ["rain", "Spain", "main", "plain"]
str2: result = ["Hertford", "Hereford", "Hampshire"]
Str =~ RegEx
ใช้ Operator =~ เบื้องต้นเปรียบเทียบ String กับ Regular Expression คืน Index แรกที่ตรง คืน nil หากไม่มี Match
สรุป
บทความนี้อธิบายการใช้ Regular Expressions (RegEx) ใน Ruby หากอยากรู้เพิ่มเติมเกี่ยวกับสิ่งที่สร้างได้กับ Ruby อ่านบทความ "What Is Ruby Code Used For?"
อยากเรียน Ruby ให้ดีขึ้น? ให้ Career Karma ช่วยหาโปรแกรมฝึกอบรมที่ดีที่สุดให้คุณ