在键中使用特殊字符的 Perl 散列替换

Perl hash substitution with special characters in keys

我当前的脚本将采用表达式,例如:

my $expression = '( a || b || c )';

并使用 sub/replace 遍历输入的每个布尔组合,如下所示:

my $keys = join '|', keys %stimhash;
$expression =~ s/($keys)\b/$stimhash{}/g;

所以例如表达式可能成立,

( 0 || 1 || 0 )

效果很好。

但是,我想允许变量(也在 %stimhash 中)包含一个标记,*.

my $expression = '( a* || b* || c* )';

此外,打印 stimhash 的键 returns:

a*|b*|c*

额外的特殊字符 *.
不正确 substituting/replacing 它给出了这个警告:

Use of uninitialized value within %stimhash in substitution iterator

我试过使用 quotemeta() 但到目前为止效果不佳。
它会降低值。替换后的示例如下所示:

( * || * || * )

如有任何建议,我们将不胜感激,

约翰

问题 1

您使用模式 a* 认为它只会匹配 a*,但 a* 意味着“0 个或更多 a”。您可以使用 quotemeta 将文本转换为与该文本匹配的正则表达式模式。

替换

my $keys = join '|', keys %stimhash;

my $keys = join '|', map quotemeta, keys %stimhash;

问题 2

\b

基本上是

(?<!\w)(?=\w)|(?<=\w)(?!\w)

*(如 space)不是单词字符。解决方案可能是更换

s/($keys)\b/$stimhash{}/g

s/($keys)(?![\w*])/$stimhash{}/g

尽管以下内容对我来说更有意义

s/(?<![\w*])($keys)(?![\w*])/$stimhash{}/g

就我个人而言,我会使用

s{([\w*]+)}{ $stimhash{} //  }eg