2014-11-02 17 views
2

我想理解如何理解工作,因为它正在做一些不同于我期望它做的事情。我读了几个答案,其中最相关的是这一个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 
+1

不确定这是否相关,但是第二个版本出现(无论如何)与第一个版本有所不同:在'whidSession < - ...'行中,'mkString“”'部分是在{}内部而不是在外部,就像在第一种情况下一样。错误? – 2014-11-02 17:42:24

+0

在第一个片段中,您使用正则表达式“rWhidArg”,但在第二个“rWhidEOL”中。也许你的第二个正则表达式匹配每个符号? – 2014-11-02 19:19:52

回答

1

要检查相应的匹配是相等的:

,但允许在一条线上的多个匹配:

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