Scala正则表达式多块捕获

Tho*_*ler 7 regex scala

我正在尝试使用Scala中的正则表达式捕获多行字符串的部分内容.输入格式如下:

val input = """some text
              |begin {
              |  content to extract
              |  content to extract
              |}
              |some text
              |begin {
              |  other content to extract
              |}
              |some text""".stripMargin
Run Code Online (Sandbox Code Playgroud)

我已经尝试了几种可能性,可以让我从begin { }块中获取文本.其中之一:

val Block = """(?s).*begin \{(.*)\}""".r

input match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
}
Run Code Online (Sandbox Code Playgroud)

我得到了NO MATCH.如果我删除\}正则表达式看起来像(?s).*begin \{(.*)它与最后一个块匹配,包括不需要的}和"一些文本".我在rubular.com检查了我的正则表达式,/.*begin \{(.*)\}/m并且至少匹配了一个块.我想当我的Scala正则表达式匹配时,我可以开始使用findAllIn匹配所有块.我究竟做错了什么?

我看一下Scala Regex启用Multiline选项,但我无法捕获所有出现的文本块,例如a Seq[String].任何帮助表示赞赏.

Dan*_*ral 10

正如Alex所说,当使用模式匹配从正则表达式中提取字段时,该模式就好像它是有界的(即使用^$).避免此问题的常用方法是先使用findAllIn.这条路:

val input = """some text
              |begin {
              |  content to extract
              |  content to extract
              |}
              |some text
              |begin {
              |  other content to extract
              |}
              |some text""".stripMargin

val Block = """(?s)begin \{(.*)\}""".r

Block findAllIn input foreach (_ match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
})
Run Code Online (Sandbox Code Playgroud)

否则,您可以.*在开头和结尾使用以绕过该限制:

val Block = """(?s).*begin \{(.*)\}.*""".r

input match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,你可能想要一个非渴望的匹配器:

val Block = """(?s)begin \{(.*?)\}""".r

Block findAllIn input foreach (_ match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
})
Run Code Online (Sandbox Code Playgroud)

  • for(Block(content) <- Block findAllIn input) println(content) (2认同)