Regexp :: Grammars

时间:2016-05-09 14:14:00

标签: regex perl regexp-grammars

在perl模块Regexp :: Grammars中,请考虑以下标记:

<token: command>       <%commands>

此标记是复杂语法的一部分,解析各种不同的句子。

此令牌匹配hash%命令中的任何单词,我已定义如下(当然,在任何函数之外):

our %commands = (
    'Basic_import'  => 1,
    'Wait'          => 1,
    'Reload'        => 1,
    'Log'           => 1,
); 

这适用于匹配关键字,例如&#34; Basic_import&#34;,&#34;等等&#34;等等。但是,我也希望它匹配像&#34; basic_import&#34;这样的字词, &#34;等待&#34;等等

如何在不必多次复制和粘贴每个关键字的情况下使此哈希大小写不敏感?因为这是复杂语法的一部分,我想使用Regexp :: Grammars,并且我不想为这个特殊的异常恢复为grep。

3 个答案:

答案 0 :(得分:4)

从文档中可以看出,<%commands>Wait的{​​{1}}相匹配,因此即使是Waiting的不区分大小写的版本也不会理想。

您通常希望匹配通用标识符,并独立检查标识符是否为有效命令。这可以防止<%commands>与Perl中的printfoo();等效。

我可以建议如下:

print foo();

如果您想要向后兼容早于5.16的Perl版本,则可以使用use feature qw( fc ); our %commands = map { fc($_) => 1 } qw( Basic_import Wait Reload Log ); <rule: command> (<ident>) <require: (?{ $commands{fc($CAPTURE)} })> <token: ident> \w+ 代替lc

答案 1 :(得分:1)

您可以使用Hash::Case::Preserve使哈希查找不区分大小写:

use strict;
use warnings 'all';

use Data::Dump;
use Hash::Case::Preserve;
use Regexp::Grammars;

tie my %commands, 'Hash::Case::Preserve';

%commands = (
    'Basic_import'  => 1,
    'Wait'          => 1,
    'Reload'        => 1,
    'Log'           => 1,
);

my $grammar = qr{

    <command>

    <token: command>    <%commands>

};  

dd \%/ if 'basic_import' =~ $grammar;

输出:

{ "" => "basic_import", "command" => "basic_import" }

请注意,在插入任何值之前,您必须tie哈希

答案 2 :(得分:0)

%commands = map { lc($_) => 1, $_ => 1 } qw(
    Basic_import
    Wait
    Reload
    Log
);