Scala正则表达式无法匹配" \ r \ n"在给定字符串中包含多个" \ r \ n"

时间:2017-08-11 00:07:34

标签: regex scala

我希望使用正则表达式abcd\r\nabc\r\nppp(abcd\r\nabc, ppp)拆分为"(.*)\r\n(.*)".r

但是正则表达式匹配失败了:

object Regex extends App {
  val r = "(.*)\r\n(.*)".r
  val str = "abcd\r\nabc\r\nppp"

  str match {
    case r(a,b) =>
      println((a,b))
    case _ =>
      println("fail - ")
  }
}

控制台打印fail -

如果再次使用正则表达式匹配abcd\r\nppp,则可以正常工作:

object Regex extends App {
  val r = "(.*)\r\n(.*)".r
  val str = "abcd\r\nppp"

  str match {
    case r(a,b) =>
      println((a,b))
    case _ =>
      println("fail - ")
  }
}

此外,我不想将\ r \ n替换为其他字符。它会浪费计算资源,因为代码用于表现敏感阶段。

由于

1 个答案:

答案 0 :(得分:1)

默认情况下,Dot与\n不匹配(不要问为什么 - 没有理由,它没有原因),因此.*在第二个\n上失败。 您可以通过为正则表达式指定DOTALL标志来更改它。这是通过将(?s)添加到模式的开头来完成的(不要问?s如何代表DOTALL ...在正则表达式世界中有很多这样的谜:)

 val r = "(?s)(.*)\r\n(.*)".r
 val str = "abcd\r\nabc\r\nppp"
 str match {
    case r(a,b) => println(a -> b)
 }

这打印    (A B C D     ABC,     PPP    )

如果您想在第一个\r\n而不是最后一个分割,请将?添加到第一个组:

val r = "(?s)(.*?)\r\n(.*)".r

这使得通配符非贪婪,因此它将匹配最短的字符串,而不是最长的字符串,这是默认值。