regex - Perl6 中的语法有点过于贪婪

标签 regex grammar raku regex-greedy

我遇到了这个迷你语法的问题,它试图匹配类似 Markdown 的 header 结构。

role Like-a-word {
    regex like-a-word { \S+ }
}

role Span does Like-a-word {
    regex span { <like-a-word>[\s+ <like-a-word>]* } 
}
grammar Grammar::Headers does Span {
    token TOP {^ <header> \v+ $}

    token hashes { '#'**1..6 }

    regex header {^^ <hashes> \h+ <span> [\h* $0]? $$}
}

我希望它匹配 ## Easier ##作为标题,但取而代之的是 ##作为 span 的一部分:
TOP
|  header
|  |  hashes
|  |  * MATCH "##"
|  |  span
|  |  |  like-a-word
|  |  |  * MATCH "Easier"
|  |  |  like-a-word
|  |  |  * MATCH "##"
|  |  |  like-a-word
|  |  |  * FAIL
|  |  * MATCH "Easier ##"
|  * MATCH "## Easier ##"
* MATCH "## Easier ##\n"
「## Easier ##
」
 header => 「## Easier ##」
  hashes => 「##」
  span => 「Easier ##」
   like-a-word => 「Easier」
   like-a-word => 「##」

问题在于[\h* $0]?似乎根本不起作用,使用 span吞噬所有可用的单词。任何的想法?

最佳答案

首先,正如其他人所指出的,<hashes>不捕获到 $0 ,而是捕获到 $<hashes> 中,所以你必须写:

regex header {^^ <hashes> \h+ <span> [\h* $<hashes>]? $$}

但这仍然不符合您想要的方式,因为 [\h* $<hashes>]?部分愉快地匹配零次出现。

正确的解决方法是不让 span匹配 ##一句话:
role Like-a-word {
    regex like-a-word { <!before '#'> \S+ }
}

role Span does Like-a-word {
    regex span { <like-a-word>[\s+ <like-a-word>]* } 
}
grammar Grammar::Headers does Span {
    token TOP {^ <header> \v+ $}

    token hashes { '#'**1..6 }

    regex header {^^ <hashes> \h+ <span> [\h* $<hashes>]? $$}
}

say Grammar::Headers.subparse("## Easier ##\n", :rule<header>);

如果您不愿意修改 like-a-word ,您还可以强制排除最终的 #像这样:
role Like-a-word {
    regex like-a-word { \S+ }
}

role Span does Like-a-word {
    regex span { <like-a-word>[\s+ <like-a-word>]* } 
}
grammar Grammar::Headers does Span {
    token TOP {^ <header> \v+ $}

    token hashes { '#'**1..6 }

    regex header {^^ <hashes> \h+ <span> <!after '#'> [\h* $<hashes>]? $$}
}

say Grammar::Headers.subparse("## Easier ##\n", :rule<header>);

关于regex - Perl6 中的语法有点过于贪婪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48110245/

相关文章:

regex - 正则表达式与 ls 的用法

regex - 如何在输入中接受超过 1 个 HTML5 模式?

javascript - 用 JavaScript 填充字符和数字数组

python - 如何修改 Python 源代码以添加新的 AST 节点?

introspection - 我可以自省(introspection)一个变量以直接发现它是用什么子集声明的吗?

raku - 为什么 temp 在 Perl 6 核心设置中不起作用?

java - 在文本中查找数字并对它们求和

grammar - 是EBNF标准的在线版本不正确,还是Mr.的章节名称不正确?帕蒂斯?

gcc - 搜索最近的 GCC GIMPLE 语法

unicode - 如何在 Perl6 中按名称搜索 Unicode 代码点?