Scala:正则表达式模式与大括号匹配?

Scala: Regular Expression pattern match with curly braces?

所以我正在为我的作业创建一个类似于 WML 的语言,作为第一步,我应该创建正则表达式来识别以下内容:

//single = "{"
//double = "{{"
//triple = "{{{"

这是我的第二个代码:

val double = "\{\{\b".r

我的测试是:

println(double.findAllIn("{{ s{{ { {{{ {{ {{x").toArray.mkString(" "))

位它不打印任何东西!它应该打印第一个、第二个、第五个和第六个标记。我已经尝试了 \b 和 \B 的每一个组合,甚至 \{{2,2} 而不是 \{\{ 但它仍然无法正常工作。有帮助吗??

附带问题,如果我想让它只匹配第一个和第五个标记,我需要做什么?

我测试了您的代码 (Scala 2.12.2 REPL),与您的 "it doesn't print anything" 语句相反,它实际上从“{{x”子字符串中打印出“{{”。

这是因为x是一个单词字符,而\b匹配第二个{x之间的位置。请记住 { 不是单词字符,与 x.

不同

根据this tutorial

It matches at a position that is called a "word boundary". This match is zero-length

There are three different positions that qualify as word boundaries:

1) Before the first character in the string, if the first character is a word character

...

至于解决方案,这取决于精确的定义,但环顾四周似乎对我有用:

"(?<!\{)\{{2}(?!\{)".r

匹配 "first, second, fifth and 6th token"。该表达式表示匹配“{{”之前和之后都没有“{”。

对于side-question:

"(?<![^ ])\{\{(?![^ ])".r //match `{` surrounded by spaces or line boundaries

或者,根据您对 "space" 的解释:

"(?<!\S)\{\{(?!\S)".r

匹配第 1 个和第 5 个标记。我不能使用积极的环视,因为我想自动考虑行的开始和结束(边界)。因此 ![^ ] 的双重否定产生了 ^$ 的隐式包含效果。或者,您可以使用:

"(?<=^|\s)\{\{(?=\s|$)".r

您可以阅读环视 here。基本上它们匹配符号或表达式作为边界;简单地说它们匹配东西但不将其包含在匹配的字符串本身中。

环顾四周的一些例子

  • (?<=z)aaa 匹配前面有 z
  • 的 "aaa"
  • (?<!z)aaa 匹配前面没有 z
  • 的 "aaa"
  • aaa(?=z) 匹配 "aaa" 后跟 z
  • aaa(?!z) 匹配 "aaa" 后面没有 z

P.S。为了让你的生活更轻松,Scala 有 """ 用于转义,所以让我们说而不是:

"(?<!\S)\{\{(?!\S)".r

你可以:

"""(?<!\S)\{\{(?!\S)""".r