Regexp::Grammars 中不区分大小写的散列键
Case-insensitive hash-keys in Regexp::Grammars
在 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。
根据文档,听起来 <%commands>
会匹配 Waiting
的 Wait
,因此即使 <%commands>
的不区分大小写的版本也不太理想。
您通常希望匹配通用标识符,并独立检查标识符是否为有效命令。这就是阻止 printfoo();
等同于 Perl 中的 print foo();
的原因。
我可以提出以下建议:
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 版本,你可以使用 lc
而不是 fc
。
您可以使用 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
散列。
%commands = map { lc($_) => 1, $_ => 1 } qw(
Basic_import
Wait
Reload
Log
);
在 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。
根据文档,听起来 <%commands>
会匹配 Waiting
的 Wait
,因此即使 <%commands>
的不区分大小写的版本也不太理想。
您通常希望匹配通用标识符,并独立检查标识符是否为有效命令。这就是阻止 printfoo();
等同于 Perl 中的 print foo();
的原因。
我可以提出以下建议:
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 版本,你可以使用 lc
而不是 fc
。
您可以使用 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
散列。
%commands = map { lc($_) => 1, $_ => 1 } qw(
Basic_import
Wait
Reload
Log
);