jjm*_*elo 7 regex grammar perl6 regex-greedy
我遇到了这个迷你语法的问题,它试图匹配像markdown一样的头部结构.
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]? $$}
}
Run Code Online (Sandbox Code Playgroud)
我希望它匹配## 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 => ?##?
Run Code Online (Sandbox Code Playgroud)
问题是,[\h* $0]?只是span吞噬了所有可用的单词,似乎根本不起作用.任何的想法?
首先,正如其他人所指出的那样,<hashes>它不会被捕获$0,而是被捕获$<hashes>,所以你必须写:
regex header {^^ <hashes> \h+ <span> [\h* $<hashes>]? $$}
Run Code Online (Sandbox Code Playgroud)
但这仍然与你想要的方式不符,因为该[\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>);
Run Code Online (Sandbox Code Playgroud)
如果你不愿意修改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>);
Run Code Online (Sandbox Code Playgroud)