【问题标题】:Perl hash substitution with special characters in keysPerl 哈希替换键中的特殊字符
【发布时间】:2015-04-29 06:36:33
【问题描述】:

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

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(),但目前效果不佳。
它会丢弃这些值。替换后的示例如下所示:

( * || * || * )

欢迎提出任何建议,

约翰

【问题讨论】:

    标签: regex perl hashtable substitution string-substitution


    【解决方案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-07-02
    • 2010-12-02
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多