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

Advanced Ruby Regular Expression Techniques

คิดว่าจะสนุกต่อจาก regex conditionals วานนี้ ดู tricks อื่นๆ ที่ทำได้กับ regular expressions ใน Ruby

Split strings ด้วย Regular Expression

คุ้นเคย split strings ด้วย text delimiter:


"one,two".split(",") # => ["one", "two"]

แต่รู้ไหม split รับ regular expression ได้?


# 用 `,` 和 `-` 做 delimiters
"one,two-three".split(/,|-/) # => ["one", "two", "three"]

# 用 comma 做 thousands separator สำหรับ US currency,
# 但用 space สำหรับ Euros
"1,000USD".split /(?=.*(USD))(?(1),| )/

Capturing Delimiters

Party trick ปกติ split string delimiters หาย:


# Commas หาย!
"one,two".split(",") # => ["one", "two"]

แต่ถ้า用 regex ใส่ delimiter ใน group split จะ capture delimiter ด้วย:


"one,two-three".split(/(,|-)/) # => ["one", ",", "two", "-", "three"]

เหตุผล: split split string ที่ boundary ของแต่ละ capture group

Abusing split

Abuse split ให้ behave เกือบ像 match โค้ด用四个 groups ใน regex split string 成 4 pieces:


"1-800-555-1212".split(/(1)-(\d{3})-(\d{3})-(\d{4})/)
# => ["", "1", "800", "555", "1212"]

Item แรกใน array ว่างเพราะ regex match entire source string

Global Matching

Default regex match pattern ครั้งเดียว โค้ดด้านล่างได้หนึ่ง match แม้มีห้า possible matches:


"12345".match /\d/ # => #

ภาษาอื่นๆ เช่น Perl flag regex "global" Ruby ไม่มีแต่有 String#scan

scan คืน array ทุก matches:


"12345".scan /\d/ # => ["1", "2", "3", "4", "5"]

有 handy block syntax:


"12345".scan /\d/ do |i|
  puts i
end

เสียดายไม่มีทาง scan string lazily เทคนิคนี้不适合 process 500mb file

Scanning with Groups

ตอนนี้คง wonder tricks 用 groups ใน scan

เสียดาย behavior predictable และ BORING Groups 产生 multi-dimensional array:


"hiho hiho".scan /(hi)(ho)/ # => [["hi", "ho"], ["hi", "ho"]]

有個 weird edge case: 用 groups 任何东西 NOT 在 group 不会 returned:


"hiho hiho".scan /(hi)ho/ # => [["hi"], ["hi"]]

Shorthand

เดิมรู้ =~ check regex match string คืน index ที่ match เริ่ม


"hiho" =~ /hi/ # 0
"hiho" =~ /ho/ # 2

有另一個 quick way check match: === operator


/hi/ === "hiho" # true

เขียน a === b 在 Ruby 問 "b 属于 a 定义的 set ไหม" ในกรณีนี้ "hiho" 属于 regex /hi/ match strings set ไหม

=== operator ใช้ภายใน case statements ของ Ruby 所以 用 regex ใน case statements ได้


case "hiho"
when /hi/
  puts "match"
end

Triple-equals operator useful ให้ methods ของตัวเอง接受 regex หรือ strings ได้

จินตนาการอยาก execute code ตอน error ยกเว้นบน pre-configured ignore list 例用 === ให้ user ระบุ string หรือ regex:


def ignored?(error)
  @ignored_patterns.any? { |x| x === error.class.name }
end

That's it!

แน่นอนมี tricks เหล่านี้散落 Ruby และ Rails หลายสิบ ถ้ามีอันนิยมบอกมา!