在一个字符串上执行两个(冲突)插值

时间:2015-08-22 19:51:41

标签: regex perl

我有一个插值函数,用来自%foo的{​​{1}}和$HV{'default'}{'foo'}取代%foo.bar

$HV{foo}{bar}

但是如果sub interpolate { my $work = "@_"; $work =~ s/\%(\w+)\.(\w+)/$HV{$1}{$2}/g; $work =~ s/\%(\w+)/$HV{'default'}{$1}/g; return $work; } 包含$HV{'foo'}{'bar'}个字符,则第二个操作会匹配它,这不是我想要的。我的第一个修复是使用

将所有%更改为%foo
%default.foo

但是这会将$work =~ s/\%(\w+)/%default\.$1/g; $work =~ s/\%(\w+)\.(\w+)/$HV{$1}{$2}/g; 更改为%foo.bar。有没有办法做我想要的而不重新做哈希?

另外,对于奖励积分,我会对正则表达式感兴趣,该正则表达式将%default.foo.bar与相应的值匹配,以使其适用于任何哈希值。

1 个答案:

答案 0 :(得分:3)

最简单的解决方案是对字符串进行单次遍历,而不是连续两次遍历:

$work =~ s{%(\w+)(?:\.(\w+))?}{
    defined $2
        ? $HV{$1}{$2}
        : $HV{default}{$1}
}eg;

要修复您的其他方法,您可以将正则表达式更改为

$work =~ s/%(\w+)(?!\.\w)/%default.$1/g;

仅在%foo后面没有.bar的情况下替换%foo.bar.baz

奖励积分:假设您要将$HV{foo}{bar}{baz}替换为sub lookup { my ($cur, @keys) = @_; $cur = $cur->{$_} for @keys; return $cur; } s{%(\w+(?:\.\w+)*)}{ lookup(\%HV, split(/\./, $1)) }eg; ,可以按以下方式完成:

    private void button1_Click(object sender, EventArgs e)
    {
        string x = textBox1.Text;
        System.Diagnostics.Process.Start("http://www.google.com/search?q="+x+"&btnI");
    }

    private void textBox1_TextChanged(object sender, EventArgs e)
    {
    }