我是新来斯卡拉。 我想匹配双引号分隔字符串,我有点受以下行为感到困惑:
如果我做到以下几点:
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
为什么没有“测试”比赛在第二种情况下?
把你的正则表达式:
"([^"]*)"(.*$)
当编译.r
,这个字符串产生一个regex
对象-它,如果它匹配它的输入串,必须产生2个捕获字符串-一个为([^"]*)
另一个为(.*$)
你。码
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
陈述的正则表达式提取的unapplySeq
方法返回2个字符串列表,因为这是正则表达式说什么它抓住。 这是不幸的,但由于正则表达式在运行时编译字符串的编译器不能帮助你在这里。
一个替代方案是使用非捕获组:
val stringRegex = """"([^"]*)"(?:.*$)"""
// ^^
那么你的代码将工作,因为regex
现在是提取对象,其unapplySeq
方法返回只有一个捕获组:
tidyTokens foreach {
case regex(token) => println (token + " matches!")
case t => println ("No match for token " + t)
}
看看在本教程中提取对象 ,就如何更好地了解apply
/ unapply
/ unapplySeq
工作。