在 Scala 中使用正規表示式

Suraj P 2023年1月30日 2022年6月15日 Scala Scala Regex
  1. Scala 中的 Regex
  2. 在 Scala 中查詢文字中的匹配項
  3. 使用 Regex 替換 Scala 中的文字
  4. 使用 Regex 在 Scala 中提取值
  5. 結論
在 Scala 中使用正規表示式

正規表示式定義了用於匹配輸入資料的通用模式。這些對於模式匹配和文字處理或解析非常有用。

在本文中,我們將學習如何在 Scala 中使用 Regex(正規表示式)。

Scala 中的 Regex

Regex 是 Scala 中的一個類,它是從 scala.util.matching.Regex 匯入的,基於 Java 包 java.util.regex,廣泛用於模式匹配和文字解析。Regex 物件可以通過兩種方式建立。

第一種方法是顯式建立 Regex 類物件。

val x = new Regex("you")

第二種方法是使用 r 方法。

val x = "You".r

讓我們看一下使用 Regex 的正規表示式的不同用例。

在 Scala 中查詢文字中的匹配項

在文字中查詢匹配項是 Regex 最常見的用例之一。

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    def main(args: Array[String])
    {
        val x = new Regex("Tony")
        val text = "Iron man is also known as Tony Stark. Tony is an Avenger"

        println(x findFirstIn text)
    }
}

輸出:

Some(Tony)

執行程式碼

在上面的程式碼中,我們使用了 findFirstIn 方法來查詢正規表示式的第一個匹配項,該方法返回一個 Option[String] 物件。

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    def main(args: Array[String])
    {
        val reg = new Regex("([0-9]{2})\\-([0-9]{3})")
        val text = "He lives in Warsaw 01-011 and she lives in Cracow 30-059"

        println((reg findAllIn text).mkString(","))
    }
}

輸出:

01-011,30-059

執行程式碼

在上面的示例中,我們使用 findAllIn 方法查詢所有匹配項並返回 MatchIterator。然後我們使用 mkString 方法將輸出轉換為由 ,(逗號)分隔的字串。

我們還有 findFirstMatchIn 方法。它的工作方式類似於 findFirstIn 方法,但返回 Option[Match]

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    def main(args: Array[String])
    {
        val reg = new Regex("([0-9]{2})\\-([0-9]{3})")
        val text = "He lives in Warsaw 01-011 and she lives in Cracow 30-059"

        val result = reg.findFirstMatchIn(text)
        println(Some("011"), for (x <- result) yield x.group(2))
    }
}

輸出:

(Some(011),Some(011))

執行程式碼

使用 Regex 替換 Scala 中的文字

這是替換文字的 Regex 的另一個用例。有時在文字解析期間,我們可能已經用其他東西替換了其中的一部分。

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    // Main method
    def main(args: Array[String])
    {
        val reg = new Regex("([0-9]{2})\\-([0-9]{3})")
        val text = "He lives in Warsaw 01-011 and she lives in Cracow 30-059"

        println(reg replaceFirstIn(text, "1234"))
    }
}

輸出:

He lives in Warsaw 1234 and she lives in Cracow 30-059

執行程式碼

在上面的程式碼中,我們使用了 replaceFirstIn 方法將文字中找到的第一個匹配項替換為字串 "1234"

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    // Main method
    def main(args: Array[String])
    {
        val reg = new Regex("([0-9]{2})\\-([0-9]{3})")
        val text = "He lives in Warsaw 01-011 and she lives in Cracow 30-059"

        println(reg replaceAllIn(text, "1234"))
   }
}

輸出:

He lives in Warsaw 1234 and she lives in Cracow 1234

執行程式碼

在上面的程式碼中,我們使用了 replaceAllIn 方法,它將在文字中找到的所有匹配項替換為 "1234"

使用 Regex 在 Scala 中提取值

當我們使用正規表示式找到匹配項時,我們可以使用 Regex 通過模式匹配來提取值。

示例程式碼:

import scala.util.matching.Regex
object myClass {

    def main(args: Array[String]) {
        val timestamp = "([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3})".r
        val time = "12:20:01.411" match {
            case timestamp(hour, minutes, _, _) => println(s"It is $minutes minutes after $hour")
        }
    }
}

輸出:

It is 20 minutes after 12

執行程式碼

在 Scala 中,預設情況下,Regex 的行為就像模式是 anchored。例如,模式被放在^$ 字元的中間,如^pattern$,但我們可以使用 UnanchoredRegex 類中的 unanchored 方法刪除這些字元。

有了這個幫助,我們可以在字串中新增額外的文字,並且仍然可以找到我們需要的內容。

示例程式碼:

import scala.util.matching.Regex
object myClass
{
    def main(args: Array[String]) {
        val timestamp = "([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{3})".r
        val temp = timestamp.unanchored
        val time = "It is 12:20:01.411 in New York" match {
            case temp(hour, minutes, _, _) => println(s"It is $minutes minutes after $hour")
        }
    }
}

輸出:

It is 20 minutes after 12

執行程式碼

Java 從 Perl 程式語言繼承了它的大部分正規表示式和它的 Regex 特性,而 Scala 從 Java 繼承了它的正規表示式語法。

讓我們看一下從 Java 中提取的一些 Scala 常用的正規表示式。

子表示式 匹配
^ 它匹配行的開頭。
$ 它與結尾的開頭相匹配。
[...] 它用於匹配括號中存在的任何單個字元。
[^...] 它用於匹配括號中不存在的任何單個字元
\\w 它用於匹配單詞字元。
\\d 它用於匹配數字。

結論

在本文中,我們瞭解了 Scala 標準庫中的 Regex 類。我們還看到了它如何提供不同的 API,幫助我們處理正規表示式的不同用例。

Author: Suraj P
Suraj P avatar Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn GitHub