gpt4 book ai didi

regex - 在 Regexp::Grammars 模块中处理空格

转载 作者:行者123 更新时间:2023-12-02 01:50:20 28 4
gpt4 key购买 nike

我有一个语法,我正在尝试借助 Regexp::Grammars 进行解析,但出于某种原因,它看起来像是有空格问题。我已设法将其减少为以下内容:

use Modern::Perl;
use v5.16;

use Regexp::Grammars;
use Data::Dumper;

my $grammar = qr{
<foo> <baz> | my <foo> is <baz>

<rule: foo> foo | fu | phoo
<rule: baz> bazz?
}ix;

while (<>) {
chomp;

if (/$grammar/) {
say Dumper(\%/);
}
else {
say "NO MATCH!!\n";
}

}

当程序运行时和任何匹配序列如

foo baz
phoo bazz
my fu is baz

进入程序返回

NO MATCH!!

但是,如果我在语法定义之前插入一个调试指令:

<debug: match>
<foo> <baz> | my <foo> is <baz>
...

我得到了我所期望的:

perl.exe : ========> Trying <grammar> from position 0
At line:1 char:5
+ perl <<<< .\test_grammar2.pl 2>&1 > output.txt
+ CategoryInfo : NotSpecified: (========> Tryin...from position 0:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

phoo bazz |...Trying <foo>

| |...Trying subpattern /foo/
| | \FAIL subpattern /foo/
| |...Trying next alternative
| |...Trying subpattern /fu/
| | \FAIL subpattern /fu/
| |...Trying next alternative
| |...Trying subpattern /phoo/
bazz | | \_____subpattern /phoo/ matched 'phoo'
| \_____<foo> matched 'phoo'
|...Trying <baz>
| |...Trying subpattern /bazz?/
[eos] | | \_____subpattern /bazz?/ matched 'bazz'
| \_____<baz> matched ' bazz'
\_____<grammar> matched 'phoo bazz'

$VAR1 = {
'' => 'phoo baz',
baz => ' bazz',
foo => 'phoo'
};

类似地,如果我在子规则和文字调用之间放置一个可选的空白序列:

<foo>\s*<baz> ...
...

我也得到了匹配。

我使用的是 Winodws 7、ActivePerl Build 1603、Perl 5.16.3 和 PowerShell。我也尝试过使用 cmd.exe 以防出现一些模糊的 PowerShell 问题,但我遇到了同样的问题。我也试过直接匹配:

my $s = q(fu baz);
if ($s =~ $grammar) {
...
}

但我遇到了同样的问题——使用相同的解决方案。

编辑:我学到了什么。

当使用 Regexp::Grammars 模块时,如果您的语法需要文字、子规则或两者之间有空格,那么您需要封装:

<foobaz>

<rule: foobaz> <foo> <baz> | my <foo> is <baz>

转义:

<foo>\ <baz> | my\ <foo>\ is\ <baz>

或插入空白序列:

<foo>\s+<baz> | my\s+<foo>\s+is\s+<baz>

最佳答案

好的,我知道问题出在哪里了。 Regexp::Grammars 表达式中的顶级匹配以标记模式(不忽略空格)而不是规则模式(忽略空格)处理。所以,要得到你想要的,你只需要添加一条顶级规则:

my $grammar = qr{
<top>

<rule: top> <foo> <baz> |
my <foo> is <baz>
<rule: foo> foo | fu | phoo
<rule: baz> bazz?
}ix;

这是我的完整程序:

use Modern::Perl;
use v5.16;

use Regexp::Grammars;
use Data::Dumper;

my $grammar = qr{
<top>

<rule: top> <foo> <baz> |
my <foo> is <baz>
<rule: foo> foo | fu | phoo
<rule: baz> bazz?
}ix;

1;
while (<>) {
chomp;

if (/$grammar/) {
say Dumper(\%/);
}
else {
say "NO MATCH!!\n";
}

}

这是我的输出:

% echo FU baz | perl grammar.pl
$VAR1 = {
'' => 'FU baz',
'top' => {
'' => 'FU baz',
'baz' => 'baz',
'foo' => 'FU'
}
};

% echo my phoo is bazz | perl grammar.pl
$VAR1 = {
'' => 'my phoo is bazz',
'top' => {
'' => 'my phoo is bazz',
'baz' => 'bazz',
'foo' => 'phoo'
}
};

Regexp::Grammars 的文档特别指出顶层是在 token 模式下完成的。添加顶级标记只会向解析树添加一层,但如果要在顶级忽略空格,我认为您没有选择。

关于regex - 在 Regexp::Grammars 模块中处理空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23165273/

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