【问题标题】:Recursive regular expression in Perl 6?Perl 6中的递归正则表达式?
【发布时间】:2019-03-01 08:44:19
【问题描述】:

我一直在尝试弄清楚如何在 Perl 6 中执行递归正则表达式。举个玩具例子,平衡括号匹配器,它将匹配 (((((())()) 内的 ((())())

  • PCRE 示例:/\((?R)?\)/

  • Onigmo 示例:(?<paren>\(\g<paren>*\))

我以为这样就可以了:

my regex paren {
  '(' ~ ')' <paren>*
}

或者更简单的

my regex paren {
  '(' <paren>* ')'
}

但是失败了

No such method 'paren' for invocant of type 'Match'
in regex paren at ...

【问题讨论】:

  • @HåkonHægland:谢谢,尤其是link 是一个不错的发现。但是,我明确尝试不查看语法,因为我想找到所有匹配的跨度,而不是从头开始解析字符串,而且我认为语法不支持这一点。也就是说,我是 P6 的菜鸟,所以我确信我错过了一些东西。
  • @HåkonHægland 我的意思是我想我可以制作一个包含 nonparen 作为我不想要的东西的语法,以及一个将收集 paren 匹配项的操作类......但这得到了复杂的快...很难相信 P6 正则表达式放弃了对 Perl 基本开创的东西的支持。

标签: regex raku


【解决方案1】:

您需要明确表明您正在调用 my-scoped 正则表达式:

my regex paren {
    '(' ~ ')' <&paren>*
}

注意已添加的&amp;。有了这个:

say "(()())" ~~ /^<&paren>$/    # 「(()())」
say "(()()" ~~ /^<&paren>$/     # Nil

虽然您有时可以在不明确写 &amp; 的情况下逃脱,但在使用它时确实可以:

say "(()())" ~~ /^<paren>$/    # 「(()())」
say "(()()" ~~ /^<paren>$/     # Nil

这仅是因为编译器发现在词法范围中定义了一个名为 paren 的正则表达式,因此将 &lt;paren&gt; 语法编译到其中。对于递归情况,直到解析正则表达式后才会安装声明,因此需要明确。

【讨论】:

  • 完美,这是缺少的部分。谢谢!
【解决方案2】:

您可以在元语法中使用~~ 对当前模式或只是其中的一部分进行递归回调。例如,您可以使用简单的正则表达式匹配平衡括号:

say "(()())" ~~ /'(' <~~>* ')'/;    # 「(()())」
say "(()()"  ~~ /'(' <~~>* ')'/;    # 「()」

Try it online!

很遗憾,尚未实现通过捕获的子规则(如~~0)进行匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多