Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Ruby Regular Expressions: Advanced Pattern Matching และ Validation

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: Advanced Pattern Matching และ Validation

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 编码!

喔 别忘 分享 这 给 朋友 如果 享受 更多 人 学习 🙂