我试图推理理解是如何起作用的,因为它正在做一些与我期望的不同的事情。我读了几个答案,其中最相关的是这个答案Scala "<-" for comprehension但是,我仍然感到困惑。
以下代码按预期工作。它打印的行与两个不同正则表达式匹配的值不相等(一个用于会话cookie中的值,另一个用于GET args中的值,只是为了给出上下文):
file.getLines().foreach { line =>
val whidSession: String = rWhidSession.findAllMatchIn(line) flatMap {m => m.group(1)} mkString ""
val whidArg: String = rWhidArg.findAllMatchIn(line) flatMap {m => m.group(1)} mkString ""
if(whidSession != whidArg) println(line)
}
以下是有问题的代码,迭代匹配字符串中的字母,因此打印该行的次数与两个值中的不同字母一样多次:
/**
* This would compare letters, regardless of the use of mkString.. even without the flatMap step.
*/
val whidTuples = for {
line <- file.getLines().toList
whidSession <- rWhidSession.findAllMatchIn(line) flatMap {m => m.group(1) mkString ""}
whidArg <- rWhidEOL.findAllMatchIn(line) flatMap {m => m.group(1) mkString ""} if whidArg != whidSession
} yield line
答案 0 :(得分:1)
检查相应的匹配是否相等:
scala> val ss = "foo/foo" :: "bar/bar" :: "foo/bar" :: Nil
ss: List[String] = List(foo/foo, bar/bar, foo/bar)
scala> val ra = "(.*)/.*".r ; val rb = ".*/(.*)".r
ra: scala.util.matching.Regex = (.*)/.*
rb: scala.util.matching.Regex = .*/(.*)
scala> for (s <- ss; ra(x) = s; rb(y) = s if x != y) yield s
res0: List[String] = List(foo/bar)
但允许一行多个匹配:
scala> val ss = "foo/foo" :: "bar/bar" :: "baz/baz foo/bar" :: Nil
ss: List[String] = List(foo/foo, bar/bar, baz/baz foo/bar)
这仍然会比较第一场比赛:
scala> val ra = """(\w*)/\w*""".r.unanchored ; val rb = """\w*/(\w*)""".r.unanchored
ra: scala.util.matching.UnanchoredRegex = (\w*)/\w*
rb: scala.util.matching.UnanchoredRegex = \w*/(\w*)
scala> for (s <- ss; ra(x) = s; rb(y) = s if x != y) yield s
res2: List[String] = List()
所以比较所有比赛:
scala> val ra = """(\w*)/\w*""".r ; val rb = """\w*/(\w*)""".r
ra: scala.util.matching.Regex = (\w*)/\w*
rb: scala.util.matching.Regex = \w*/(\w*)
scala> for (s <- ss; ma <- ra findAllMatchIn s; mb <- rb findAllMatchIn s; ra(x) = ma; rb(y) = mb if x != y) yield s
res3: List[String] = List(baz/baz foo/bar, baz/baz foo/bar, baz/baz foo/bar)
或
scala> for (s <- ss; (ma, mb) <- (ra findAllMatchIn s) zip (rb findAllMatchIn s); ra(x) = ma; rb(y) = mb if x != y) yield s
res4: List[String] = List(baz/baz foo/bar)
scala> for (s <- ss; (ra(x), rb(y)) <- (ra findAllMatchIn s) zip (rb findAllMatchIn s) if x != y) yield s
res5: List[String] = List(baz/baz foo/bar)
匹配ra(x) = ma
不应该重新评估正则表达式而只是ma group 1
。