我对Scala很新,特别是很棒的模式匹配。但是,我觉得这段代码不起作用。我创建了一个包含匹配单词的“字典”,然后我使用了for-comprehension,这样每一行都会与字典中的单词相匹配。
这是用于创建正则表达式的地图。
val dictionary = Map(
"""will""" -> 1,
"""going to""" -> 2,
"""future""" -> 3
)
这是主要的for循环:
for (
ln <- file.getLines();
(word, loc) <- dictionary
){
val regex = word.r
ln match {
case regex(ln) => {totalLine += 1
println("Match detected: " + word)
val originalElem = doc.BOWVector(dictionary.get(ln).get)
doc.BOWVector.updated(dictionary.get(ln).get, originalElem+1) //vector is updated
}
case _ => {totalLine += 1}
}
}
当我使用ln.contains("will")
时,它有效!然而正则表达式将无法正常工作。为什么?
答案 0 :(得分:2)
更近一点:
scala> for (ln <- List("I will go"); (word, loc) <- dictionary) {
| val r = word.r.unanchored
| ln match { case r() => println(s"Yes $word") ; case _ => println(s"No $word") }}
Yes will
No going to
No future
默认的锚定正则表达式为^will$
。
如果您不想担心捕获组,请使用“序列通配符”。
scala> for (ln <- List("I will go"); (word, loc) <- dictionary) {
| val r = word.r.unanchored
| ln match { case r(_*) => println(s"Yes $word") ; case _ => println(s"No $word") }}
Yes will
No going to
No future
scala> val dictionary = Map("wi(l*)" -> 1)
dictionary: scala.collection.immutable.Map[String,Int] = Map(wi(l*) -> 1)
scala> for (ln <- List("I will go"); (word, loc) <- dictionary) {
| val r = word.r.unanchored
| ln match { case r(_*) => println(s"Yes $word") ; case _ => println(s"No $word") }}
Yes wi(l*)
scala> for (ln <- List("I will go"); (word, loc) <- dictionary) {
| val r = word.r.unanchored
| ln match { case r(ells) => println(s"Yes $ells") ; case _ => println(s"No $word") }}
Yes ll
答案 1 :(得分:1)
问题是scala.util.matching.Regex.unapplySeq
返回匹配的组
如果正则表达式不包含组(您的情况),则在模式匹配中应使用以下形式:
scala> val regex1 = "foo".r
regex1: scala.util.matching.Regex = foo
scala> "foo" match { case regex1() => "match" }
res0: String = match
对于匹配的组,它将是
scala> val regex2 = "(foo)".r
regex2: scala.util.matching.Regex = (foo)
scala> "foo" match { case regex2(group) => s"match $group" }
res1: String = match foo
组的数量可以是任意的,但case
语句中的参数数量应该匹配
scala> val regex3 = "(foo)(\\d)".r
regex3: scala.util.matching.Regex = (foo)(\d)
scala> "foo1" match { case regex3(word, digit) => s"match $word $digit" }
res2: String = match foo 1
另外,请参阅unapplySeq scaladoc
的示例