5

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

<token: command>       <%commands>

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

这个标记匹配哈希 %commands 中的任何单词,我定义如下(当然,在任何函数之外):

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

这适用于匹配“Basic_import”、“Wait”等关键字。但是,我也希望它匹配“basic_import”、“wait”等词。

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

4

3 回答 3

5

从文档来看,这听起来像是<%commands>匹配Waitof Waiting,所以即使是不区分大小写的版本<%commands>也不太理想。

您通常希望匹配一个通用标识符,并独立检查该标识符是否为有效命令。这是阻止printfoo();等同print foo();于 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+

如果您想向后兼容早于 5.16 的 Perl 版本,您可能可以不使用 usinglc而不是。fc

于 2016-05-09T14:57:23.657 回答
2

您可以使用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,您必须先进行哈希处理。

于 2016-05-09T15:13:39.997 回答
0
%commands = map { lc($_) => 1, $_ => 1 } qw(
    Basic_import
    Wait
    Reload
    Log
);
于 2019-08-20T12:46:21.923 回答