Ruby 正則表達(dá)式

2022-09-27 11:29 更新

正則表達(dá)式是一種特殊序列的字符,它通過使用有專門語(yǔ)法的模式來匹配或查找其他字符串或字符串集合。

語(yǔ)法

正則表達(dá)式從字面上看是一種介于斜杠之間或介于跟在 %r 后的任意分隔符之間的模式,如下所示:

/pattern/
/pattern/im    # 可以指定選項(xiàng)
%r!/usr/local! # 一般的分隔的正則表達(dá)式

實(shí)例

#!/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
嘗試一下 ?

這將產(chǎn)生以下結(jié)果:

Line1 contains Cats

正則表達(dá)式修飾符

正則表達(dá)式從字面上看可能包含一個(gè)可選的修飾符,用于控制各方面的匹配。修飾符在第二個(gè)斜杠字符后指定,如上面實(shí)例所示。下標(biāo)列出了 可能的修飾符:

修飾符 描述
i 當(dāng)匹配文本時(shí)忽略大小寫。
o 只執(zhí)行一次 #{} 插值,正則表達(dá)式在第一次時(shí)就進(jìn)行判斷。
x 忽略空格,允許在正則表達(dá)式中進(jìn)行注釋。
m 匹配多行,把換行字符識(shí)別為正常字符。
u,e,s,n 把正則表達(dá)式解釋為 Unicode(UTF-8)、EUC、SJIS 或 ASCII。如果沒有指定修飾符,則認(rèn)為正則表達(dá)式使用的是源編碼。

就像字符串通過 %Q 進(jìn)行分隔一樣,Ruby 允許您以 %r 作為正則表達(dá)式的開頭,后面跟著任意分隔符。這在描述包含大量您不想轉(zhuǎn)義的斜杠字符時(shí)非常有用。

# 下面匹配單個(gè)斜杠字符,不轉(zhuǎn)義
%r|/|               

# Flag 字符可通過下面的語(yǔ)法進(jìn)行匹配
%r[</(.*)>]i  

正則表達(dá)式模式

除了控制字符,(+ ? . * ^ $ ( ) [ ] { } | \),其他所有字符都匹配本身。您可以通過在控制字符前放置一個(gè)反斜杠來對(duì)控制字符進(jìn)行轉(zhuǎn)義。

下表列出了 Ruby 中可用的正則表達(dá)式語(yǔ)法。

模式 描述
^ 匹配行的開頭。
$ 匹配行的結(jié)尾。
. 匹配除了換行符以外的任意單字符。使用 m 選項(xiàng)時(shí),它也可以匹配換行符。
[...] 匹配在方括號(hào)中的任意單字符。
[^...] 匹配不在方括號(hào)中的任意單字符。
re* 匹配前面的子表達(dá)式零次或多次。
re+ 匹配前面的子表達(dá)式一次或多次。
re? 匹配前面的子表達(dá)式零次或一次。
re{ n} 匹配前面的子表達(dá)式 n 次。
re{ n,} 匹配前面的子表達(dá)式 n 次或 n 次以上。
re{ n, m} 匹配前面的子表達(dá)式至少 n 次至多 m 次。
a| b 匹配 a 或 b。
(re) 對(duì)正則表達(dá)式進(jìn)行分組,并記住匹配文本。
(?imx) 暫時(shí)打開正則表達(dá)式內(nèi)的 i、 m 或 x 選項(xiàng)。如果在圓括號(hào)中,則只影響圓括號(hào)內(nèi)的部分。
(?-imx) 暫時(shí)關(guān)閉正則表達(dá)式內(nèi)的 i、 m 或 x 選項(xiàng)。如果在圓括號(hào)中,則只影響圓括號(hào)內(nèi)的部分。
(?: re) 對(duì)正則表達(dá)式進(jìn)行分組,但不記住匹配文本。
(?imx: re) 暫時(shí)打開圓括號(hào)內(nèi)的 i、 m 或 x 選項(xiàng)。
(?-imx: re) 暫時(shí)關(guān)閉圓括號(hào)內(nèi)的 i、 m 或 x 選項(xiàng)。
(?#...) 注釋。
(?= re) 使用模式指定位置。沒有范圍。
(?! re) 使用模式的否定指定位置。沒有范圍。
(?> re) 匹配無(wú)回溯的獨(dú)立模式。
\w 匹配單詞字符。
\W 匹配非單詞字符。
\s 匹配空白字符。等價(jià)于 [\t\n\r\f]。
\S 匹配非空白字符。
\d 匹配數(shù)字。等價(jià)于 [0-9]。
\D 匹配非數(shù)字。
\A 匹配字符串的開頭。
\Z 匹配字符串的結(jié)尾。如果存在換行符,則只匹配到換行符之前。
\z 匹配字符串的結(jié)尾。
\G 匹配最后一個(gè)匹配完成的點(diǎn)。
當(dāng)在括號(hào)外時(shí)匹配單詞邊界,當(dāng)在括號(hào)內(nèi)時(shí)匹配退格鍵(0x08)。
\B 匹配非單詞邊界。
\n, \t, etc. 匹配換行符、回車符、制表符,等等。
\1...\9 匹配第 n 個(gè)分組子表達(dá)式。
\10 如果已匹配過,則匹配第 n 個(gè)分組子表達(dá)式。否則指向字符編碼的八進(jìn)制表示。

正則表達(dá)式實(shí)例

字符

實(shí)例 描述
/ruby/ 匹配 "ruby"
匹配 Yen 符號(hào)。Ruby 1.9 和 Ruby 1.8 支持多個(gè)字符。

字符類

實(shí)例 描述
/[Rr]uby/ 匹配 "Ruby" 或 "ruby"
/rub[ye]/ 匹配 "ruby" 或 "rube"
/[aeiou]/ 匹配任何一個(gè)小寫元音字母
/[0-9]/ 匹配任何一個(gè)數(shù)字,與 /[0123456789]/ 相同
/[a-z]/ 匹配任何一個(gè)小寫 ASCII 字母
/[A-Z]/ 匹配任何一個(gè)大寫 ASCII 字母
/[a-zA-Z0-9]/ 匹配任何一個(gè)括號(hào)內(nèi)的字符
/[^aeiou]/ 匹配任何一個(gè)非小寫元音字母的字符
/[^0-9]/ 匹配任何一個(gè)非數(shù)字字符

特殊字符類

實(shí)例 描述
/./ 匹配除了換行符以外的其他任意字符
/./m 在多行模式下,也能匹配換行符
/\d/ 匹配一個(gè)數(shù)字,等同于 /[0-9]/
/\D/ 匹配一個(gè)非數(shù)字,等同于 /[^0-9]/
/\s/ 匹配一個(gè)空白字符,等同于 /[ \t\r\n\f]/
/\S/ 匹配一個(gè)非空白字符,等同于 /[^ \t\r\n\f]/
/\w/ 匹配一個(gè)單詞字符,等同于 /[A-Za-z0-9_]/
/\W/ 匹配一個(gè)非單詞字符,等同于 /[^A-Za-z0-9_]/

重復(fù)

實(shí)例 描述
/ruby?/ 匹配 "rub" 或 "ruby"。其中,y 是可有可無(wú)的。
/ruby*/ 匹配 "rub" 加上 0 個(gè)或多個(gè)的 y。
/ruby+/ 匹配 "rub" 加上 1 個(gè)或多個(gè)的 y。
/\d{3}/ 剛好匹配 3 個(gè)數(shù)字。
/\d{3,}/ 匹配 3 個(gè)或多個(gè)數(shù)字。
/\d{3,5}/ 匹配 3 個(gè)、4 個(gè)或 5 個(gè)數(shù)字。

非貪婪重復(fù)

這會(huì)匹配最小次數(shù)的重復(fù)。

實(shí)例 描述
/<.*>/ 貪婪重復(fù):匹配 "<ruby>perl>"
/<.*?>/ 非貪婪重復(fù):匹配 "<ruby>perl>" 中的 "<ruby>"

通過圓括號(hào)進(jìn)行分組

實(shí)例 描述
/\D\d+/ 無(wú)分組: + 重復(fù) \d
/(\D\d)+/ 分組: + 重復(fù) \D\d 對(duì)
/([Rr]uby(, )?)+/ 匹配 "Ruby"、"Ruby, ruby, ruby",等等

反向引用

這會(huì)再次匹配之前匹配過的分組。

實(shí)例 描述
/([Rr])uby&\1ails/ 匹配 ruby&rails 或 Ruby&Rails
/(['"])(?:(?!\1).)*\1/ 單引號(hào)或雙引號(hào)字符串。\1 匹配第一個(gè)分組所匹配的字符,\2 匹配第二個(gè)分組所匹配的字符,依此類推。

替換

實(shí)例 描述
/ruby|rube/ 匹配 "ruby" 或 "rube"
/rub(y|le))/ 匹配 "ruby" 或 "ruble"
/ruby(!+|\?)/ "ruby" 后跟一個(gè)或多個(gè) ! 或者跟一個(gè) ?

這需要指定匹配位置。

實(shí)例 描述
/^Ruby/ 匹配以 "Ruby" 開頭的字符串或行
/Ruby$/ 匹配以 "Ruby" 結(jié)尾的字符串或行
/\ARuby/ 匹配以 "Ruby" 開頭的字符串
/Ruby\Z/ 匹配以 "Ruby" 結(jié)尾的字符串
/Ruby/ 匹配單詞邊界的 "Ruby"
/rub\B/ \B 是非單詞邊界:匹配 "rube" 和 "ruby" 中的 "rub",但不匹配單獨(dú)的 "rub"
/Ruby(?=!)/ 如果 "Ruby" 后跟著一個(gè)感嘆號(hào),則匹配 "Ruby"
/Ruby(?!!)/ 如果 "Ruby" 后沒有跟著一個(gè)感嘆號(hào),則匹配 "Ruby"

圓括號(hào)的特殊語(yǔ)法

實(shí)例 描述
/R(?#comment)/ 匹配 "R"。所有剩余的字符都是注釋。
/R(?i)uby/ 當(dāng)匹配 "uby" 時(shí)不區(qū)分大小寫。
/R(?i:uby)/ 與上面相同。
/rub(?:y|le))/ 只分組,不進(jìn)行 \1 反向引用

搜索和替換

subgsub 及它們的替代變量 sub!gsub! 是使用正則表達(dá)式時(shí)重要的字符串方法。

所有這些方法都是使用正則表達(dá)式模式執(zhí)行搜索與替換操作。subsub! 替換模式的第一次出現(xiàn),gsubgsub! 替換模式的所有出現(xiàn)。

subgsub 返回一個(gè)新的字符串,保持原始的字符串不被修改,而 sub!gsub! 則會(huì)修改它們調(diào)用的字符串。

下面是一個(gè)實(shí)例:

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-

phone = "138-3453-1111 #這是一個(gè)電話號(hào)碼"

# 刪除 Ruby 的注釋
phone = phone.sub!(/#.*$/, "")   
puts "電話號(hào)碼 : #{phone}"

# 移除數(shù)字以外的其他字符
phone = phone.gsub!(/\D/, "")    
puts "電話號(hào)碼 : #{phone}"

嘗試一下 ?

這將產(chǎn)生以下結(jié)果:

電話號(hào)碼 : 138-3453-1111 
電話號(hào)碼 : 13834531111

下面是另一個(gè)實(shí)例:

#!/usr/bin/ruby

text = "rails are rails, really good Ruby on Rails"

# 把所有的 "rails" 改為 "Rails"
text.gsub!("rails", "Rails")

# 把所有的單詞 "Rails" 都改成首字母大寫
text.gsub!(/rails/, "Rails")

puts "#{text}"
嘗試一下 ?

這將產(chǎn)生以下結(jié)果:

Rails are Rails, really good Ruby on Rails


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)