Ruby 正規表示式
正規表示式是一種特殊序列的字符,它透過使用有專門語法的模式來匹配或尋找字串集合。
正規表示式用事先定義好的一些特定字元、及這些特定字元的組合,組成一個"規則字串",這個"規則字串"用來表示對字串的一種過濾邏輯。
正規表示式從字面上看是一種介於斜線之間或介於跟在%r 後的任意分隔符號之間的模式,如下所示:
/pattern/
/pattern/im # 可以指定选项
%r!/usr/local! # 使用分隔符的正则表达式
#!/usr/bin/ruby
line1 = "Cats are smarter than dogs";
line2 = "Dogs also like meat";
if ( line1 =~ /Cats(.*)/ )
puts "Line1 contains Cats"
end
if ( line2 =~ /Cats(.*)/ )
puts "Line2 contains Dogs"
end
#以上實例運行輸出結果為:
Line1 contains Cats
正規表示式從字面上看可能包含一個可選的修飾符,用於控制各方面的匹配。修飾符在第二個斜線字元後指定,如上面實例所示。下標列出了可能的修飾符:
| ##描述 |
---|
##i | #當符合文字時忽略大小寫。 |
o | 只執行一次 #{} 插值,正規表示式在第一次時就會判斷。 |
x | 忽略空格,允許在整個表達式中放入空白符和註解。 |
m | 符合多行,把換行字元辨識為正常字元。 |
u,e,s,n | 將正規表示式解釋為 Unicode(UTF-8)、EUC、SJIS 或 ASCII。如果沒有指定修飾符,則認為正規表示式使用的是來源編碼。 |
就像字串透過 %Q 進行分隔一樣,Ruby 允許您以 %r 作為正規表示式的開頭,後面跟著任意分隔符號。這在描述包含大量您不想轉義的斜線字元時非常有用。
# 下面匹配单个斜杠字符,不转义
%r|/|
# Flag 字符可通过下面的语法进行匹配
%r[</(.*)>]i
除了控製字符,(+ ? . * ^ $ ( ) [ ] { } | \),其他所有字符都匹配本身。您可以透過在控製字元前放置一個反斜線來對控製字元進行轉義。
下表列出了 Ruby 中可用的正規表示式語法。
模式 | 描述 |
---|
#^ | 符合行的開頭。 |
$ | 符合行的結尾。 |
. | 符合除了換行符號以外的任意單字元。使用 m 選項時,它也可以匹配換行符。 |
[...] | 符合在方括號中的任意單字元。 |
[^...] | 符合不在方括號中的任意單字元。 |
re* | 符合前面的子表達式是零次或多次。 |
re+ | 符合前面的子表達式一次或多次。 |
re? | 符合前面的子運算式是零次或一次。 |
re{ n} | 符合前面的子表達式 n 次。 |
re{ n,} | 符合前面的子表達式 n 次或 n 次以上。 |
re{ n, m} | 比符合前面的子表達式至少 n 次至多 m 次。 |
a| b | 符合 a 或 b。 |
(re) | 將正規表示式分組,並記住符合文字。 |
(?imx) | 暫時開啟正規表示式內的 i、 m 或 x 選項。如果在圓括號中,則只影響圓括號內的部分。 |
(?-imx) | 暫時關閉正規表示式內的 i、 m 或 x 選項。如果在圓括號中,則只影響圓括號內的部分。 |
(?: re) | 將正規表示式分組,但不記住符合文字。 |
(?imx: re) | 暫時開啟圓括號內的 i、 m 或 x 選項。 |
(?-imx: re) | 暫時關閉圓括號內的 i、 m 或 x 選項。 |
(?#...) | 註解。 |
(?= re) | 使用模式指定位置。沒有範圍。 |
(?! re) | 使用模式的否定指定位置。沒有範圍。 |
(?> re) | 符合無回溯的獨立模式。 |
\w | 符合單字字元。 |
\W | 符合非單字字元。 |
\s | 符合空白字元。等價於 [\t\n\r\f]。 |
\S | 符合非空白字元。 |
\d | 符合數字。等價於 [0-9]。 |
\D | 符合非數字。 |
\A | 符合字串的開頭。 |
\Z | 符合字串的結尾。如果存在換行符,則只匹配到換行符之前。 |
\z | 符合字串的結尾。 |
\G | 符合最後一個符合完成的點。 |
\b | 當括號外時符合單字邊界,當括號內時符合退格鍵(0x08)。 |
\B | 符合非單字邊界。 |
\n, \t, etc. | 匹配換行符、回車符、製表符,等等。 |
\1...\9 | 符合第 n 個分組子運算式。 |
\10 | 如果已配對過,則符合第 n 個分組子運算式。否則指向字元編碼的八進位表示。 |
字元
##實例 | 描述 |
/ruby/ | 匹配"ruby" |
¥ | 符合Yen 符號。 Ruby 1.9 和 Ruby 1.8 支援多個字元。 |
字元類別#實例 | 描述 |
/[Rr]uby/ | 匹配"Ruby" 或"ruby" |
#/rub[ye]/ | 匹配"ruby"或"rube" |
/[aeiou]/ | 匹配任何一個小寫元音字母 |
/[0- 9]/ | 匹配任何一個數字,與/[0123456789]/ 相同 |
/[a-z]/ | 匹配任何一個小寫ASCII 字母 |
/[A-Z]/ | 符合任何一個大寫ASCII 字母 |
/[a-zA-Z0-9 ]/ | 符合任何一個括號內的字元 |
/[^aeiou]/ | 符合任何一個非小寫元音字母的字元 |
/[^0-9]/ | 符合任何一個非數字字元 |
##特殊字元類別
實例描述 | |
#/./符合除了換行符號以外的其他任意字元 | |
/./m在多行模式下,也能符合換行符號 | |
/\d /符合一個數字,等同於/[0-9]/ | |
/\D/符合一個非數字,等同於/ [^0-9]/ | |
/\s/符合一個空白字符,等同於/[ \t\r\n\f]/ | |
/\S/符合一個非空白字符,等同於/[^ \t\r\n\f]/ | |
#/\w/符合一個單字字符,等同於/[A-Za-z0-9_]/ | |
/\W/ 匹配一個非單字字符,等同於/[^A-Za-z0-9_]/ | |
#重複
實例描述 | |
/ruby?/符合"rub" 或"ruby"。其中,y 是可有可無的。 | |
/ruby*/符合 "rub" 加上 0 個或多個的 y。 | |
/ruby+/符合 "rub" 加上 1 個或多個的 y。 | |
/\d{3}/剛好符合 3 個數字。 | |
/\d{3,}/符合 3 個或多個數字。 | |
/\d{3,5}/符合 3 個、4 個或 5 個數字。 | |
非貪婪重複
這會符合最小次數的重複。
實例 | 描述 |
---|
#/<.*>/ | 貪婪重複:匹配"<ruby>perl>" |
/<.*?>/ | 非貪婪重複:匹配"<ruby>perl> " 中的"<ruby>" |
透過圓括號進行分組
#描述/\D\d+/ | 無分組: + 重複\d |
---|
/(\D\d )+/ | 分組: + 重複\D\d 對 |
#/([Rr]uby(, )?)+/ | ##匹配"Ruby"、"Ruby, ruby, ruby",等等 |
#反向引用這會再次匹配先前匹配過的分組。 | 實例 | 描述
---|
| #/([Rr])uby&\1ails/ | 符合ruby&rails 或Ruby&Rails
| /(['"])(?:(?!\1).)*\1/ | 單引號或雙引號字串。
| 實例 | 描述
#/ruby|rube/
符合"ruby" 或"rube "
/rub(y|le))/ | 匹配"ruby" 或"ruble" |
##/ruby (!+|\?)/"ruby" 後面跟著一個或多個! 或跟一個? | |
錨 | 這需要指定匹配位置。符合以"Ruby" 開頭的字串或行 |
/Ruby$/ | 符合以"Ruby" 結尾的字串或行 |
/\ARuby/ | 符合以"Ruby" 開頭的字串 |
/Ruby\Z/ | 符合以"Ruby" 結尾的字串 |
/\bRuby\b/ | #符合單字邊界的"Ruby" |
/\brub\B/ | \B 是非單字邊界:匹配"rube" 和"ruby" 中的"rub",但不匹配單獨的"rub" |
/Ruby(?=!)/ | 如果"Ruby" 後面跟著一個驚嘆號,則匹配"Ruby" |
/Ruby(?!!)/
###如果"Ruby" 後面沒有跟著一個感嘆號,則符合"Ruby"#############圓括號的特殊語法
實例 | #描述 |
---|
##/R(?#comment) / | 匹配"R"。所有剩餘的字元都是註釋。 |
/R(?i)uby/ | 當符合 "uby" 時不區分大小寫。 |
/R(?i:uby)/ | 與上面相同。 |
/rub(?:y|le))/ | 只分組,不進行\1 反向引用 |
搜尋與取代sub 和gsub 及它們的替代變數sub! 和gsub! 是使用正規表示式時重要的字串方法。
所有這些方法都是使用正規表示式模式執行搜尋與取代操作。 sub 和 sub! 替換模式的第一次出現,gsub 和 gsub! 替換模式的所有出現。
sub 和gsub 傳回一個新的字串,保持原始的字串不被修改,而sub! 和 gsub! 則會修改它們所呼叫的字串。
下面是一個實例:#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
phone = "138-3453-1111 #这是一个电话号码"
# 删除 Ruby 的注释
phone = phone.sub!(/#.*$/, "")
puts "电话号码 : #{phone}"
# 移除数字以外的其他字符
phone = phone.gsub!(/\D/, "")
puts "电话号码 : #{phone}"
以上實例運行輸出結果為:电话号码 : 138-3453-1111
电话号码 : 13834531111
下面是另一個實例:
#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
text = "rails 是 rails, Ruby on Rails 非常好的 Ruby 框架"
# 把所有的 "rails" 改为 "Rails"
text.gsub!("rails", "Rails")
# 把所有的单词 "Rails" 都改成首字母大写
text.gsub!(/\brails\b/, "Rails")
puts "#{text}"
以上實例執行輸出結果為:Rails 是 Rails, Ruby on Rails 非常好的 Ruby 框架
#