# 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/ | 單引號或雙引號字符串。\1 匹配第一個分組所匹配的字符,\2 匹配第二個分組所匹配的字符,依此類推。 |
## 替換
| 實例 | 描述 |
| --- | --- |
| /ruby|rube/ | 匹配 "ruby" 或 "rube" |
| /rub(y|le))/ | 匹配 "ruby" 或 "ruble" |
| /ruby(!+|\?)/ | "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
phone = "2004-959-559 #This is Phone Number"
# 刪除 Ruby 的注釋
phone = phone.sub!(/#.*$/, "")
puts "Phone Num : #{phone}"
# 移除數字以外的其他字符
phone = phone.gsub!(/\D/, "")
puts "Phone Num : #{phone}"
```
這將產生以下結果:
```
Phone Num : 2004-959-559
Phone Num : 2004959559
```
下面是另一個實例:
```
#!/usr/bin/ruby
text = "rails are rails, really good Ruby on Rails"
# 把所有的 "rails" 改為 "Rails"
text.gsub!("rails", "Rails")
# 把所有的單詞 "Rails" 都改成首字母大寫
text.gsub!(/\brails\b/, "Rails")
puts "#{text}"
```
這將產生以下結果:
```
Rails are Rails, really good Ruby on Rails
```
- Ruby 基礎
- Ruby 簡介
- Ruby 環境
- Ruby 安裝 - Unix
- Ruby 安裝 - Windows
- Ruby 命令行選項
- Ruby 環境變量
- Ruby 語法
- Ruby 數據類型
- Ruby 類和對象
- Ruby 類案例
- Ruby 變量
- Ruby 運算符
- Ruby 注釋
- Ruby 判斷
- Ruby 循環
- Ruby 方法
- Ruby 塊
- Ruby 模塊(Module)
- Ruby 字符串(String)
- Ruby 數組(Array)
- Ruby 哈希(Hash)
- Ruby 日期 & 時間(Date & Time)
- Ruby 范圍(Range)
- Ruby 迭代器
- Ruby 文件的輸入與輸出
- Ruby File 類和方法
- Ruby Dir 類和方法
- Ruby 異常
- Ruby 高級
- Ruby 面向對象
- Ruby 正則表達式
- Ruby 數據庫訪問 - DBI 教程
- Ruby CGI 編程
- Ruby CGI方法
- Ruby CGI Cookies
- Ruby CGI Sessions
- Ruby 發送郵件 - SMATP
- Ruby Socket 編程
- Ruby XML, XSLT 和 XPath 教程
- Ruby Web Services 應用 - SOAP4R
- Ruby 多線程
- 免責聲明