Regex Scala正则表达式多块捕获

Regex Scala正则表达式多块捕获,regex,scala,Regex,Scala,我试图用Scala中的正则表达式捕获多行字符串的一部分。 输入的格式如下: val input = """some text |begin { | content to extract | content to extract |} |some text |begin { | other cont

我试图用Scala中的正则表达式捕获多行字符串的一部分。 输入的格式如下:

val input = """some text
              |begin {
              |  content to extract
              |  content to extract
              |}
              |some text
              |begin {
              |  other content to extract
              |}
              |some text""".stripMargin
我已经尝试了几种可能的方法,可以将文本从
begin{
}
块中取出。其中一项:

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

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

我看了一下,但无法捕获所有出现的文本块,例如,
Seq[String]

非常感谢您的帮助。

在进行匹配时,我相信需要完整的匹配含蓄性。您的匹配相当于:

val Block = """^(?s).*begin \{(.*)\}$""".r
如果在末尾添加.*则有效:

val Block = """(?s).*begin \{(.*)\}.*""".r
我找不到任何关于这方面的文档,但我遇到了同样的问题。

如前所述,当使用模式匹配从正则表达式中提取字段时,模式的行为就好像它是有界的(即,使用
^
$
)。避免此问题的通常方法是首先使用
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")
})
否则,您可以在开头和结尾使用
*
,以绕过该限制:

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

input match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
}
顺便说一句,您可能需要一个不热心的匹配者:

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

Block findAllIn input foreach (_ match {
  case Block(content) => println(content)
  case _ => println("NO MATCH")
})

作为对其他答案的补充,我想指出存在的,这让你可以写以下内容:

import kantan.regex.ops._

// The type parameter is the type as which to decode results,
// the value parameters are the regular expression to apply and the group to
// extract data from.
input.evalRegex[String]("""(?s)begin \{(.*?)\}""", 1).toList
这将产生:

List(Success(
  content to extract
  content to extract
), Success(
  other content to extract
))

你知道这有没有记录在案吗?亚历克斯,现在我不确定。我对Regex做了很多工作,甚至扩展了库,以至于我都记不起库提供了什么!例如,我打算在输入映射(u组0)
中编写
Block findAllMatchesIn input map(
),这时我发现这个方法在库中并不存在。例如(Block(content)谢谢,Ken。我应该考虑至少提供一个理解示例。在LHS上进行模式匹配是聪明的。