我刚刚开始探索perl6语法.如何组成一个标记"行",它匹配行的开头和结尾之间的所有内容?我试过以下但没有成功:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS grammar sample { token TOP {} token line { ^^.*$$ } } my $match = sample.parse($txt); say $match [0];
Pierre VIGIE.. 11
我在这里可以看到你的语法中的2个问题,这里的第一个是令牌行,^^和$$是开始和结束的锚点,但你可以在它们之间有新的行.为了说明,我们先使用一个简单的正则表达式,而不使用Grammar:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS if $txt ~~ m/^^.*$$/ { say "match"; say $/; }
运行它,输出是:
match ?row 1 row 2 row 3?
你看到正则表达式与期望的匹配更多,但第一个问题不存在,这是因为棘轮,与令牌匹配将无法工作:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS my regex r {^^.*$$}; if $txt ~~ &r { say "match regex"; say $/; } else { say "does not match regex"; } my token t {^^.*$$}; if $txt ~~ &t { say "match token"; say $/; } else { say "does not match token"; }
运行它,输出是:
match regex ?row 1 row 2 row 3? does not match token
我不确定为什么,但令牌和锚点$$似乎并不能很好地协同工作.但你想要的是搜索除换行符之外的所有内容,即\ N*以下语法主要解决你的问题:
grammar sample { token TOP {} token line {\N+} }
但是它只匹配第一次出现,因为你只搜索一行,你可能想要做的是搜索一行+一个可选的垂直空格(在你的情况下,你的字符串末尾有一个新行,但是我想你想在最后一行采取最后一行,即使最后没有新行),重复几次:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS grammar sample { token TOP {[\v?]*} token line {\N+} } my $match = sample.parse($txt); for $match -> $l { say $l; }
该脚本的输出开始:
?row 1? ?row 2? ?row 3?
还可以帮助您使用和调试语法,2个非常有用的模块:Grammar :: Tracer和Grammar :: Debugger.只需将它们包含在脚本的开头即可.Tracer展示了由您的语法完成的匹配的彩色树.调试器允许您实时地逐步查看它.
我在这里可以看到你的语法中的2个问题,这里的第一个是令牌行,^^和$$是开始和结束的锚点,但你可以在它们之间有新的行.为了说明,我们先使用一个简单的正则表达式,而不使用Grammar:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS if $txt ~~ m/^^.*$$/ { say "match"; say $/; }
运行它,输出是:
match ?row 1 row 2 row 3?
你看到正则表达式与期望的匹配更多,但第一个问题不存在,这是因为棘轮,与令牌匹配将无法工作:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS my regex r {^^.*$$}; if $txt ~~ &r { say "match regex"; say $/; } else { say "does not match regex"; } my token t {^^.*$$}; if $txt ~~ &t { say "match token"; say $/; } else { say "does not match token"; }
运行它,输出是:
match regex ?row 1 row 2 row 3? does not match token
我不确定为什么,但令牌和锚点$$似乎并不能很好地协同工作.但你想要的是搜索除换行符之外的所有内容,即\ N*以下语法主要解决你的问题:
grammar sample { token TOP {} token line {\N+} }
但是它只匹配第一次出现,因为你只搜索一行,你可能想要做的是搜索一行+一个可选的垂直空格(在你的情况下,你的字符串末尾有一个新行,但是我想你想在最后一行采取最后一行,即使最后没有新行),重复几次:
my $txt = q:to/EOS/; row 1 row 2 row 3 EOS grammar sample { token TOP {[\v?]*} token line {\N+} } my $match = sample.parse($txt); for $match -> $l { say $l; }
该脚本的输出开始:
?row 1? ?row 2? ?row 3?
还可以帮助您使用和调试语法,2个非常有用的模块:Grammar :: Tracer和Grammar :: Debugger.只需将它们包含在脚本的开头即可.Tracer展示了由您的语法完成的匹配的彩色树.调试器允许您实时地逐步查看它.
你原来的aproach可以通过工作
grammar sample { token TOP {+ %% \n } token line { ^^ .*? $$ } }
就个人而言,我不会尝试锚定line
和使用,\N
如已经建议的那样.