【问题标题】:Scala: Regular Expression pattern match with curly braces?Scala:正则表达式模式与花括号匹配?
【发布时间】:2018-08-05 04:13:56
【问题描述】:

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

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

这是我的第二个代码:

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

我的测试是:

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

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

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

【问题讨论】:

    标签: regex scala parsing curly-braces wml


    【解决方案1】:

    我测试了您的代码(Scala 2.12.2 REPL),与您的“它不打印任何内容”语句相反,它实际上从“{{x”子字符串中打印“{{”出现。

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

    根据this tutorial

    它在称为“单词边界”的位置匹配。这个匹配是零长度的

    有资格作为单词边界的三个不同位置:

    1) 在字符串的第一个字符之前,如果第一个字符是 单词字符

    ...

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

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

    它匹配“第一个、第二个、第五个和第六个令牌”。该表达式表示匹配“{{”不在“{”之前且不在“{”之后。

    附加问题:

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

    或者,取决于您对“空间”的解释:

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

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

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

    您可以阅读有关外观的信息here。基本上它们匹配符号或表达式作为边界;只是说它们匹配内容,但不将其包含在匹配的字符串本身中。

    一些环视的例子

    • (?&lt;=z)aaa 匹配前面有 z 的“aaa”
    • (?&lt;!z)aaa 匹配前面没有 z 的“aaa”
    • aaa(?=z) 匹配 "aaa" 后跟 z
    • aaa(?!z) 匹配 "aaa" 后面没有 z

    附:只是为了让你的生活更轻松,Scala 有""" 用于转义,所以让我们说:

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

    你可以:

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

    【讨论】:

    • 谢谢!尚未对其进行测试,但想解释一下括号中的每个符号块的实际作用?
    • @user7552492 这些是环顾四周,我在答案中添加了解释。基本上它们有点像匹配组(如"ab(za)k".r 匹配“abzak”,但您可以将“za”提取为match.group(1)),但无需以编程方式提取值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多