gpt4 book ai didi

regex - Perl6 解析文件

转载 作者:行者123 更新时间:2023-12-01 23:09:41 26 4
gpt4 key购买 nike

作为实践,我正在尝试解析一些标准文本,这些文本是 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

我想使用 Perl6 语法,并且想在单独的标记或正则表达式中捕获每个字段。于是,我做了如下语法:

grammar zpool {
regex TOP { \s+ [ <keyword> <collection> ]+ }
token keyword { "pool: " | "state: " | "status: " | "action: " | "scan: " | "config: " | "errors: " }
regex collection { [<:!keyword>]* }
}

我的想法是正则表达式找到一个关键字,然后开始收集所有数据,直到下一个关键字。但是,每次,我都会得到“pool:” -> 所有剩余的文本。

 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

我不知道如何让它在找到关键字时停止吃字符,然后将其视为另一个关键字。

最佳答案

问题 1

你写了<:!keyword>而不是 <!keyword> .那不是你想要的。您需要删除 : .

<:foo> P6 正则表达式中的语法 matches a single character with the specified Unicode property , 在这种情况下属性 :foo这又意味着 :foo(True) .

还有 <:!keyword>匹配具有 Unicode 属性 :keyword(False) 的单个字符.

但是没有 Unicode 属性 :keyword .

因此,否定断言将始终为真,并且每次都会匹配输入的单个字符。

所以你知道,这个模式只是在文本的其余部分中咀嚼它。

问题 2

一旦你解决了问题 1,就会出现第二个问题。

<:!keyword>匹配具有 Unicode 属性 :keyword(False) 的单个字符.每次匹配时,它都会自动咀嚼一些输入(单个字符)。

相比之下,<!keyword>如果匹配则不消耗任何输入。 你必须确保使用它的模式会咀嚼输入。


解决这两个问题后,您将获得预期的输出。 (您将看到的下一个问题是 config 关键字不起作用,因为输入文件示例中 : 中的 config: 后面没有空格。)


所以,进行一些清理工作:

my @keywords = <pool state status action scan config errors> ;

say grammar zpool {
token TOP { \s+ [ <keyword> <collection> ]* }
token keyword { @keywords ': ' }
token collection { [ <!keyword> . ]* }
}

我已将所有模式切换为 token声明。一般情况下,请始终使用 token除非你知道你需要别的东西。 (regex 启用回溯。如果你不小心,这会大大减慢速度。rule 使规则中的空格变得很重要。)

我已将关键字提取到一个数组中。 @keywords表示 @keywords[0] | @keywords[1] | ... .

我添加了一个 .<!keyword> 之后在最后一个模式中(消耗一个字符的输入值,以避免在 <!foo> 不消耗任何输入的情况下会发生的无限循环)。

如果您还没有看到它们,请注意 available grammar debugging options是你的 friend 。

关于regex - Perl6 解析文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47602397/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com