鍍金池/ 教程/ Scala/ 正規(guī)表達(dá)式
定義 Extractor
正規(guī)表達(dá)式
Extractors 和 Seq 模式
可變參數(shù)的 Extractors
無(wú)參數(shù)和帶一個(gè)參數(shù)的模式定義
分解 Email 地址的例子

正規(guī)表達(dá)式

Extractor 一個(gè)特別有用的應(yīng)用是正規(guī)表達(dá)式,Scala 支持正規(guī)表達(dá)式,尤其是和 Extractor 配合使用時(shí)顯得非常便利。

生成正規(guī)表達(dá)式

Scala 繼承了 Java 的正規(guī)表達(dá)式的語(yǔ)法規(guī)則。這里我們假定你了解正規(guī)表達(dá)式。Scala 的正規(guī)表達(dá)式相關(guān)的類型定義在包 scala.util.matching 中。

創(chuàng)建一個(gè)正規(guī)表達(dá)式是使用 RegEx 類型,例如:

scala> import scala.util.matching.Regex
import scala.util.matching.Regex
scala> val Deciaml = new Regex("(-)?(\\d+)(\\.\\d*)?")
Deciaml: scala.util.matching.Regex = (-)?(\d+)(\.\d*)?

這里構(gòu)建了一個(gè)可以識(shí)別數(shù)值的正規(guī)表達(dá)式。這個(gè)表達(dá)式中使用多個(gè)\轉(zhuǎn)義,對(duì)于復(fù)雜的正規(guī)表達(dá)式來(lái)說(shuō),有時(shí)顯得太復(fù)雜,很容易出錯(cuò),Scala 允許你使用原始的正規(guī)表達(dá)式(無(wú)需轉(zhuǎn)義),這可以通過(guò)將正規(guī)表達(dá)式包含著”””字符串中,比如重寫(xiě)上面的正規(guī)表達(dá)式如下:

val Deciaml = new Regex("""(-)?(\d+)(\.\d*)?""")

此外還有一個(gè)更簡(jiǎn)潔的方法,是在字符串后使用.r 操作符,例如:

scala> val Deciaml = """(-)?(\d+)(\.\d*)?""".r
Deciaml: scala.util.matching.Regex = (-)?(\d+)(\.\d*)?

.r 為 StringOps 的方法,它把一個(gè)字符串轉(zhuǎn)換為 Regex 對(duì)象。

使用正規(guī)表達(dá)式查找字符串

scala 支持下面幾種正規(guī)表達(dá)式的查找方法:

  • regex findFirstIn Str 查找第一個(gè)匹配的字符串,返回 Option 類型
  • regex findAllIn str 查找所有匹配的字符串,返回 Interator 類型
  • regex findPrefixOf str 從字符串開(kāi)頭檢查是否匹配正規(guī)表達(dá)式,返回 Option 類型。

例如:

scala> val Decimal = """(-)?(\d+)(\.\d*)?""".r
Decimal: scala.util.matching.Regex = (-)?(\d+)(\.\d*)?
scala> val input = " for -1.0 to 99 by 3"
input: String = " for -1.0 to 99 by 3"
scala> for(s <- Decimal findAllIn input) println(s)
-1.0
99
3
scala> Decimal findFirstIn input
res5: Option[String] = Some(-1.0)
scala> Decimal findPrefixOf input
res6: Option[String] = None

使用正規(guī)表達(dá)式分解數(shù)據(jù)

Scala 所有定義的正規(guī)表達(dá)式都定義了一個(gè) Extractor,可以用來(lái)解析正規(guī)表達(dá)式中對(duì)應(yīng)的分組,比如前面定義的Decimal定義了三個(gè)分組,可以直接用來(lái)解析一個(gè)浮點(diǎn)數(shù):

scala> val Decimal(sign,integerpart,decimalpart) = "-1.23"
sign: String = -
integerpart: String = 1
decimalpart: String = .23

如果對(duì)應(yīng)的分組查找不到,則返回 Null,比如:

scala> val Decimal(sign,integerpart,decimalpart) = "1.0"
sign: String = null
integerpart: String = 1
decimalpart: String = .0

這種分解方法同樣可以應(yīng)用到 for 表達(dá)式中,例如:

for(Decimal(s,i,d) <- Decimal findAllIn input) 
    println ("sign: " +s + ",integer:" +
    i + ",deciaml:" +d)
sign: -,integer:1,deciaml:.0
sign: null,integer:99,deciaml:null
sign: null,integer:3,deciaml:null