Scala正则表达式:findAll和match ...之间的不一致

时间:2016-03-22 13:38:05

标签: regex scala

我有一个与pattern.findFirstMatchIn()匹配但与match ... case解包声明不匹配的Scala正则表达式:

val pattern = "\"(\\d+?)\",\"(.*?)\",(.+)$".r
val line = "\"1795\",\"title\",\"desc"

println(pattern.findFirstMatchIn(line).isDefined)

val pattern2Unpacking = line match {
  case pattern( category_id, title, description) =>
    true
  case _ => false
}

println(pattern2Unpacking)

要匹配的行是"1795","title","desc

,缺少尾随引用是有意的。

输出为truefalse,而不是true

我查看了this answerthis,但我无法将解决方案与我的问题联系起来。省略边界匹配器不会改变任何东西。

这里出了什么问题?

更新以下评论

剧透:以下报告的部分明显怪异原因是我的数据包含IDE未显示的字符,这是在这些情况下需要注意的事项。要深入解释实际发生的情况,请参阅接受的答案。

这是我的IntelliJ的截图。最重要的代码是@WiktorStribiżew链接的复制粘贴。底部的代码是我基于这篇文章的代码。截屏中包含输出窗口。这不是恶作剧,我发现这有点可怕。

更新2

这更好:http://ideone.com/KsIIc1

不,我既没假冒截图,也没有破解ideone.com玩恶作剧。

enter image description here

1 个答案:

答案 0 :(得分:1)

这里的区别在于findFirstMatchIn如何使用正则表达式模式:它不会将它用作锚定模式,而$some_existing_varvar1使用锚定 em>版本。如果您阅读reference,您将看到findFirst方法不使用锚定模式。

现在,如果原始字符串末尾包含U + 2028(LINE SEPARATOR)字符并且match锚定位在模式的末尾,为什么findFirst找到匹配?这是因为$可以在字符串的末尾匹配,或者恰好在字符串末尾的最后一个换行符处(等于\Z anchor):

  

输入结束但最终terminator,如果有的话

当Scala锚定正则表达式时,它似乎使用$逻辑,并且仅匹配字符串的最末端(尽管reference says它使用\z和{{1} })。

因此,有两种方法可以解决这个问题:

  • 在模式的开头添加^ DOTALL修饰符(demo):
    $
  • 在定义正则表达式模式(demo)时使用(?s)
    val pattern = "(?s)\"(\\d+?)\",\"(.*?)\",(.+)$".r