-1

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

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* )';

此外,打印 stimhash 的键返回:

a*|b*|c*

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

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

我尝试使用 quotemeta() 但到目前为止没有很好的结果。
它会丢弃这些值。替换后的示例如下所示:

( * || * || * )

任何建议表示赞赏,

约翰

4

1 回答 1

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
于 2015-02-27T15:39:17.317 回答