use*_*164 3 regex grammar perl6
作为练习,我试图解析一些标准文本,它是shell命令的输出.
pool: thisPool
state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(5) for details.
scan: none requested
config:
NAME STATE READ WRITE CKSUM
homePool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD5000AZLX-00CL5A0_WD-WCC3F7NUE93C ONLINE 0 0 0
ata-WDC_WD5000AZLX-00CL5A0_WD-WCC3F7RE2A4F ONLINE 0 0 0
cache
ata-KINGSTON_SV300S37A60G_50026B7261025D7E-part3 ONLINE 0 0 0
errors: No known data errors
Run Code Online (Sandbox Code Playgroud)
我想使用Perl6语法,我想在单独的令牌或正则表达式中捕获每个字段.所以,我做了以下语法:
grammar zpool {
regex TOP { \s+ [ <keyword> <collection> ]+ }
token keyword { "pool: " | "state: " | "status: " | "action: " | "scan: " | "config: " | "errors: " }
regex collection { [<:!keyword>]* }
}
Run Code Online (Sandbox Code Playgroud)
我的想法是正则表达式找到一个关键字,然后开始收集所有数据,直到下一个关键字.但是,每次,我只得到"池:" - >所有剩余的文本.
keyword => ?pool: ?
collection => ?homePool
state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
the pool may no longer be accessible by software that does not support
the features. See zpool-features(5) for details.
scan: none requested
config:
NAME STATE READ WRITE CKSUM
homePool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-WDC_WD5000AZLX-00CL5A0_WD-WCC3F7NUE93C ONLINE 0 0 0
ata-WDC_WD5000AZLX-00CL5A0_WD-WCC3F7RE2A4F ONLINE 0 0 0
cache
ata-KINGSTON_SV300S37A60G_50026B7261025D7E-part3 ONLINE 0 0 0
errors: No known data errors
?
Run Code Online (Sandbox Code Playgroud)
我不知道如何让它在找到关键字时停止吃字符,然后将其视为另一个关键字.
问题1
你写的<:!keyword>不是<!keyword>.那不是你想要的.你需要删除:.
<:foo>P6正则表达式中的语法将单个字符与指定的Unicode属性匹配,在这种情况下,该属性:foo反过来意味着:foo(True).
并将<:!keyword>单个字符与Unicode属性匹配:keyword(False).
但是没有Unicode属性:keyword.
因此,否定断言将始终为真,并且每次始终匹配单个输入字符.
因此,正如您所知,模式只是通过文本的其余部分.
问题2
一旦解决问题1,就会出现第二个问题.
<:!keyword>使用Unicode属性匹配单个字符:keyword(False).每次匹配时,它会自动弹出一些输入(单个字符).
相反,<!keyword>如果匹配则不消耗任何输入.你必须确保使用它的模式能够输入.
解决这两个问题后,您将获得预期的输出.(您将看到的下一个问题是config关键字不起作用,因为输入文件示例:中的config:in后面没有空格.)
所以,有一些清理:
my @keywords = <pool state status action scan config errors> ;
say grammar zpool {
token TOP { \s+ [ <keyword> <collection> ]* }
token keyword { @keywords ': ' }
token collection { [ <!keyword> . ]* }
}
Run Code Online (Sandbox Code Playgroud)
我已将所有模式切换为token声明.一般情况下,token除非您知道自己需要其他东西,否则请务必使 (regex启用回溯.如果你不小心的话,这可能会大大降低速度.rule使规则中的空格显着.)
我已将关键字提取到数组中.@keywords手段@keywords[0] | @keywords[1] | ....
我在最后一个模式中添加了一个.after <!keyword>(消耗一个字符的输入值,以避免在<!foo>不消耗任何输入的情况下会发生的无限循环).
如果您还没有看到它们,请注意可用的语法调试选项是您的朋友.
心连心
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |