Ruby regular expressions (ruby regex สั้นๆ) ช่วยหา patterns เฉพาะใน strings เพื่อ extract data ประมวลผลต่อ
Use cases พบบ่อย: validation และ parsing
เช่น: email address ด้วย ruby regex define valid email address 长什么样 程序 能 区分 valid 和 invalid email

Ruby regular expressions 定义 在 两个 forward slashes 中间 区别 从 其他 language syntax 简单 expressions match 单词 或 单字母
例子:
# หา คำ 'like' "Do you like cats?" =~ /like/
คืน index ของ first occurrence ถ้าเจอ (successful match) หรือ nil ไม่เจอ ถ้าไม่แคร์ index ใช้ String#include? method
อีกวิธีเช็ก string match regex: 用 match method:
if "Do you like cats?".match(/like/) puts "Match found!" end
现在: 学 怎么 建立 advanced patterns match, capture, replace dates, phone numbers, emails, URLs, etc.
Character Classes
Character class 定义 range 或 list characters 要 match 如 [aeiou] match vowels 任何ตัว
例子: String 包含 vowel?
def contains_vowel(str)
str =~ /[aeiou]/
end
contains_vowel("test") # returns 1
contains_vowel("sky") # returns nil
不 考虑 character 数量 稍后 看 怎么做
Ranges
用 ranges match 多字母 数字 不用 打 全部 如 [2-5] = [2345] Ranges 有用:
- [0-9] match 数字 0-9
- [a-z] match 字母 a-z (no caps)
- [^a-z] negated range
例子: String 包含 数字?
def contains_number(str)
str =~ /[0-9]/
end
contains_number("The year is 2015") # returns 12
contains_number("The cat is black") # returns nil
Remember: return value 用 `=~` 是 string index 或 `nil`
Shorthand syntax character ranges:
- \w 等于 [0-9a-zA-Z_]
- \d 同 [0-9]
- \s match white space (tabs, space, newline)
Negative forms:
- \W 不在 [0-9a-zA-Z_]
- \D 不是 数字
- \S 不是 space
Dot . match ทุกอย่าง ยกเว้น new lines ต้องการ literal . escape it
例子: Escaping special characters
# 不 escape letter match "5a5" "5a5".match(/\d.\d/) # 这 情况 只有 literal dot match "5a5".match(/\d\.\d/) # nil "5.5".match(/\d\.\d/) # match
Modifiers
จนนี้ match single character ใช้ pattern modifiers match multiple characters
| Modifier | 描述 |
|---|---|
| + | 1 或 更多 |
| * | 0 或 更多 |
| ? | 0 或 1 |
| {3,5} | 3 到 5 |
รวม ทุกอย่าง 学 创建 complex regular expressions
例子: 长得像 IP address?
# Note: 也 match invalid IP 如 999.999.999.999 但 这 只 关心 format
def ip_address?(str)
# 用 !! 转 return value 成 boolean
!!(str =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
end
ip_address?("192.168.1.1") # returns true
ip_address?("0000.0000") # returns false
Exact String Matching
需要 exact matches 要 modifier 类型 例子 看 什么 意思:
# 想 找 string exactly 4 letters 长 这 还 match 因为 有 超过 4 但 不 是 要
"Regex are cool".match /\w{4}/
# 代用 'beginning of line' 和 'end of line' modifiers
"Regex are cool".match /^\w{4}$/
# 这 次 不 match 例子 人为 因为 用 .size 找 长度 但 觉得 传达 想法 了
Match strictly เริ่ม string ไม่ใช่ ทุกบรรทัด (หลัง \n) 用 \A 和 \Z 代替 ^ 和 $
Capture Groups
Capture groups capture 部分 match reuse 后来 部分 要 capture 括号 括起來
例子: Parsing log file
Line = Struct.new(:time, :type, :msg)
LOG_FORMAT = /(\d{2}:\d{2}) (\w+) (.*)/
def parse_line(line)
line.match(LOG_FORMAT) { |m| Line.new(*m.captures) }
end
parse_line("12:41 INFO User has logged in.")
# 产生 objects 像 这样:
#
例子 用 .match 不是 =~ method 这 回 MatchData object 有 match, nil ไม่มี MatchData class 有 methods 多 看 documentation 学 更多!
要 boolean (true/false) 用 match? method Ruby 2.4+ มี 已经 做 这 也 เร็วกว่า match 因为 Ruby 不 创建 MatchData object
เข้าถึง captured data 用 .captures method 或 当 MatchData object 像 array index 0 full match indexes ต่อไป matched groups
要 first capture group:
m = "John 31".match /\w+ (\d+)/ m[1] # 31
Non-capturing groups: group expressions 不有 performance penalty Named groups 也 好 复杂 expressions 读 容易
| Syntax | 描述 |
|---|---|
(?:...) |
Non-capturing group |
(?<foo>...) |
Named group |
例子: Named Groups
m = "David 30".match /(?\w+) (?\d+)/ m[:age] # => "30" m[:name] # => "David"
Named group 回 MatchData object เข้าถึง อ่าน results
Look Ahead 和 Look Behind
Advanced technique 可能 ไม่ 有 在 所有 regex implementations Ruby 的 regex engine 做 ได้ 看 怎么 利用
Look ahead 让 我们 peek 看 有 specific match 前面 或 后面
| Name | 描述 |
|---|---|
| (?=pat) | Positive lookahead |
| (?<=pat) | Positive lookbehind |
| (?!pat) | Negative lookahead |
| (?<!pat) | Negative lookbehind |
例子: 有 数字 前面 有 至少 1 字母?
def number_after_word?(str)
!!(str =~ /(?<=\w) (\d+)/)
end
number_after_word?("Grade 99")
Ruby 的 Regex Class
Ruby regular expressions 是 instances ของ Regexp class 多半 不 直接 用 这 class 但 知 也 好 🙂
puts /a/.class # Regexp
用途 可能: 创建 regex 从 string:
regexp = Regexp.new("a")
อีกวิธีสร้าง regexp:
regexp = %r{\w+}
Regex Options
ตั้ง options บน regex ทำให้พฤติกรรมต่าง
| Options | 描述 |
|---|---|
| i | ruby regex case insensitive |
| m | dot matches newline |
| x | ignore whitespace |
用 options 加 letter ท้าย regex หลัง closing /
像这样:
"abc".match?(/[A-Z]/i)
Formatting Long Regular Expressions
Complex Ruby regular expressions อ่านยาก ช่วย 打成 หลายบรรทัด 用 'x' modifier format นี้ 也 允许 comments 在 regex
例子:
LOG_FORMAT = %r{
(\d{2}:\d{2}) # Time
\s(\w+) # Event type
\s(.*) # Message
}x
Ruby regex: Putting It All Together
Regular expressions 用 กับ Ruby methods 多:
- .split
- .scan
- .gsub
- 和 更多...
例子: Match all words from string 用 .scan
"this is some string".scan(/\w+/) # => ["this", "is", "some", "string"]
例子: Extract all numbers from string
"The year was 1492.".scan(/\d+/) # => ["1492"]
例子: Capitalize all words in string
str = "lord of the rings"
str.gsub(/\w+/) { |w| w.capitalize } # => "Lord Of The Rings"
例子: Validate email address
email = "test@example.com" !!email.match(/\A[\w.+-]+@\w+\.\w+\z/) # true
例子 最后 用 !! 转 result 成 boolean (true/false) หรือ 用 match? method Ruby 2.4+ 已经 做 这 也 更快
结论
Regular expressions เก๋แต่อาจ tricky 用 tool 如 rubular.com 建立 ruby regex 互动 方式 Rubular 也 有 Ruby regex cheat sheet 有用 现在 轮 你 打开 editor 编码!
喔 别忘 分享 这 给 朋友 如果 享受 更多 人 学习 🙂