Scala正则表达式(由双引号分隔的字符串)

时间:2013-02-27 18:12:04

标签: regex scala double-quotes

我是scala的新手。我试图匹配由双引号分隔的字符串,我对以下行为感到有点困惑:

如果我执行以下操作:

val stringRegex = """"([^"]*)"(.*$)"""
val regex = stringRegex.r
val tidyTokens = Array[String]("1", "\"test\"", "'c'", "-23.3")
tidyTokens.foreach {
    token => if (token.matches (stringRegex)) println (token + " matches!")
}

我得到了

"test" matches!

否则,如果我执行以下操作:

tidyTokens.foreach {
    token => token match {
        case regex(token) => println (token + " matches!")
        case _ => println ("No match for token " + token)
    }
}

我得到了

No match for token 1
No match for token "test"
No match for token 'c'
No match for token -23.3

为什么不在第二种情况下“测试”匹配?

1 个答案:

答案 0 :(得分:9)

拿你的正则表达式:

 "([^"]*)"(.*$)

使用.r进行编译时,此字符串会生成一个regex对象 - 如果它与输入字符串匹配,则必须产生 2 捕获的字符串 - 一个用于{{ 1}}和([^"]*)的另一个。你的代码

(.*$)

应该反映这一点,所以也许你想要

  case regex(token) => ...

或者只是

  case regex(token, otherStuff) => ...

为什么呢?因为 case regex(token, _) => ... 语法有效,因为case regex(matchedCaputures...)是一个 具有regex方法的对象。 unapplySeq将(大致)翻译为:

case regex(token) => ...

case List(token) => ... 返回List(token)的位置:

regex.unapplySeq( inputString )

您的正则表达式与字符串 regex.unapplySeq("\"test\"") // Returns Some(List("test", "")) 匹配,但在"test"语句中,正则表达式提取程序的case方法返回 2 字符串列表,因为这是正则表达式说它抓住了。这很不幸,但编译器在这里无法帮助你,因为正则表达式是在运行时从字符串编译的。

一种替代方案是使用非捕获组:

unapplySeq

然后你的代码就可以了,因为 val stringRegex = """"([^"]*)"(?:.*$)""" // ^^ 现在将成为一个提取器对象 regex方法仅返回一个捕获的组:

unapplySeq

查看Extractor Objects上的教程,以便更好地理解 tidyTokens foreach { case regex(token) => println (token + " matches!") case t => println ("No match for token " + t) } / apply / unapply如何运作。