Scala 正則表示式



本章解釋了 Scala 如何透過 `scala.util.matching` 包中提供的 **Regex** 類支援正則表示式。

嘗試以下示例程式,我們將嘗試從語句中找出單詞 **Scala**。

示例

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = "Scala".r
      val str = "Scala is Scalable and cool"
      
      println(pattern findFirstIn str)
   }
}

將上述程式儲存為 **Demo.scala**。以下命令用於編譯和執行此程式。

命令

\>scalac Demo.scala
\>scala Demo

輸出

Some(Scala)

我們建立一個字串並在其上呼叫 `r()` 方法。Scala 會隱式地將字串轉換為 RichString 並呼叫該方法以獲取 Regex 例項。要查詢正則表示式的第一個匹配項,只需呼叫 `findFirstIn()` 方法。如果我們想查詢匹配單詞的所有出現而不是隻查詢第一次出現,我們可以使用 `findAllIn()` 方法,如果目標字串中有多個 Scala 單詞,這將返回所有匹配單詞的集合。

您可以使用 `mkString()` 方法連線結果列表,並且可以使用管道符 (|) 搜尋 Scala 的小寫和大寫形式,並且可以使用 **Regex** 建構函式或 `r()` 方法來建立模式。

嘗試以下示例程式。

示例

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = new Regex("(S|s)cala")
      val str = "Scala is scalable and cool"
      
      println((pattern findAllIn str).mkString(","))
   }
}

將上述程式儲存為 **Demo.scala**。以下命令用於編譯和執行此程式。

命令

\>scalac Demo.scala
\>scala Demo

輸出

Scala,scala

如果要替換匹配的文字,我們可以使用 `replaceFirstIn()` 替換第一個匹配項或使用 `replaceAllIn()` 替換所有出現。

示例

object Demo {
   def main(args: Array[String]) {
      val pattern = "(S|s)cala".r
      val str = "Scala is scalable and cool"
      
      println(pattern replaceFirstIn(str, "Java"))
   }
}

將上述程式儲存為 **Demo.scala**。以下命令用於編譯和執行此程式。

命令

\>scalac Demo.scala
\>scala Demo

輸出

Java is scalable and cool

形成正則表示式

Scala 從 Java 繼承其正則表示式語法,而 Java 又繼承了 Perl 的大部分特性。以下只是一些示例,作為複習應該足夠了:

下表列出了 Java 中可用的所有正則表示式元字元語法。

子表示式 匹配
^ 匹配行首。
$ 匹配行尾。
. 匹配除換行符之外的任何單個字元。使用 m 選項允許它也匹配換行符。
[...] 匹配括號中的任何單個字元。
[^...] 匹配括號中不存在的任何單個字元
\\A 整個字串的開頭
\\z 整個字串的結尾
\\Z 整個字串的結尾,但允許最終換行符。
re* 匹配前面表示式的 0 次或多次出現。
re+ 匹配前面表示式的 1 次或多次出現
re? 匹配前面表示式的 0 次或 1 次出現。
re{ n} 匹配前面表示式的正好 n 次出現。
re{ n,} 匹配前面表示式的 n 次或多次出現。
re{ n, m} 匹配前面表示式的至少 n 次最多 m 次出現。
a|b 匹配 a 或 b。
(re) 對正則表示式進行分組並記住匹配的文字。
(?: re) 對正則表示式進行分組而不記住匹配的文字。
(?> re) 匹配不回溯的獨立模式。
\\w 匹配單詞字元。
\\W 匹配非單詞字元。
\\s 匹配空格。等效於 [\t\n\r\f]。
\\S 匹配非空格。
\\d 匹配數字。等效於 [0-9]。
\\D 匹配非數字。
\\A 匹配字串的開頭。
\\Z 匹配字串的結尾。如果存在換行符,則匹配換行符之前的字元。
\\z 匹配字串的結尾。
\\G 匹配上次匹配結束的位置。
\\n 反向引用到捕獲組編號“n”
\\b 在括號之外匹配單詞邊界。在括號內匹配退格鍵 (0x08)。
\\B 匹配非單詞邊界。
\\n, \\t, etc. 匹配換行符、回車符、製表符等。
\\Q 轉義(引用)直到 \\E 的所有字元
\\E 結束由 \\Q 開始的引用

正則表示式示例

示例 描述
. 匹配除換行符之外的任何字元
[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] 匹配數字以外的任何內容
\\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 個數字
\\D\\d+ 無分組:+ 重複 \\d
(\\D\\d)+/ 分組:+ 重複 \\D\d 對
([Rr]uby(, )?)+ 匹配“Ruby”、“Ruby, ruby, ruby”等。

**注意** - 上述字串中的每個反斜槓都出現兩次。這是因為在 Java 和 Scala 中,單個反斜槓是字串文字中的跳脫字元,而不是出現在字串中的普通字元。因此,您需要編寫“\\”而不是“\”才能在字串中獲得單個反斜槓。

嘗試以下示例程式。

示例

import scala.util.matching.Regex

object Demo {
   def main(args: Array[String]) {
      val pattern = new Regex("abl[ae]\\d+")
      val str = "ablaw is able1 and cool"
      
      println((pattern findAllIn str).mkString(","))
   }
}

將上述程式儲存為 **Demo.scala**。以下命令用於編譯和執行此程式。

命令

\>scalac Demo.scala
\>scala Demo

輸出

able1
廣告