使用键中的特殊字符进行Perl哈希替换

时间:2015-02-26 18:27:17

标签: regex perl hashtable substitution string-substitution

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

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

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

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

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

( 0 || 1 || 0 )

这很有效。

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

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

此外,打印刺激的键返回:

a*|b*|c*

没有用额外的特殊字符替换/替换,*。
它给出了这个警告:

  

在替换迭代器中使用%stimhash中未初始化的值

我尝试使用quotemeta()但到目前为止没有取得好成绩 它会降低价值。替换后的示例如下:

( * || * || * )

感谢任何建议,

约翰

1 个答案:

答案 0 :(得分:1)

问题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)

但是*(就像空格一样)不是一个单词字符。解决方案可能是替换

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

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

虽然以下对我更有意义

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

就个人而言,我会使用

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