我有一个翻译字典作为哈希:
my %dict = { hello => 'hola', goodbye => 'adios' , ... }
(实际用例不是人类语言翻译!我正在用一些其他值替换一堆令牌。这仅仅是例如。)
如何将每个应用于字符串?显然我可以循环它们并将每个传递给s/$key/$value/
,但是我必须引用它们,这样如果搜索或替换中有(例如)/
,它就不会中断。
在PHP中有strtr($subject, $replacement_pairs_array)
- Perl中有类似内容吗?
答案 0 :(得分:6)
首先,您的哈希初始化已关闭:哈希初始化为列表:
my %dict = ( hello => 'hola', goodbye => 'adios' , ... );
或者您可以使用哈希引用:
my $dict = { hello => 'hola', goodbye => 'adios' , ... };
这是一个标量。
使用字符串中的值替换键很容易:
s/$_/$dict{$_}/g for keys %dict;
除非
%dict = (a => b, b => c)
应该将"ab"
转换为"bc"
(而不是"cc"
,因为上述解决方案可能会或可能不会,哈希顺序是随机的。).
,+
或()
。通过使用quotemeta
函数转义正则表达式元字符可以避免这种情况。传统的方法是构建一个匹配所有键的正则表达式:
my $keys_regex = join '|', map quotemeta, keys %dict;
然后:
$string =~ s/($keys_regex)/$dict{$1}/g;
解决了所有这些问题。
在正则表达式构建代码中,我们首先使用map quotemeta
转义所有键,然后使用|
连接字符串以构建匹配所有键的正则表达式。由此产生的正则表达式非常有效。
这可以保证字符串的每个部分只翻译一次。
答案 1 :(得分:2)
%dict = ( 'hello' => 'hola', 'goodbye' => 'adios' );
my $x="hello bob, goodbye sue";
my $r=join("|",keys %dict);
$x=~s/($r)/$dict{$1}/ge;
print $x;
这显示了一种方法。
将哈希键转换为交替的正则表达式,即“hello | goodbye”,查找与该表达式的匹配项,然后使用找到的键查找哈希值中的值。使用g标志将regexp全局或重复应用于字符串,并使用e标志将替换表达式计算为perl而不是文字替换
答案 2 :(得分:1)
似乎有一个CPAN module会执行此操作