3

我有一个翻译字典作为哈希:

my %dict = { hello => 'hola', goodbye => 'adios' , ... }

(实际用例不是人类语言翻译!我正在用一些其他值替换大量标记。这只是示例。)

如何将这些中的每一个应用于字符串?显然,我可以循环它们并将它们传递给每个,s/$key/$value/但是我必须引用它们,这样如果搜索或替换(例如)/在其中,它就不会中断。

在 PHP 中有strtr($subject, $replacement_pairs_array)- 在 Perl 中有类似的东西吗?

4

3 回答 3

7

首先,您的哈希初始化已关闭:哈希被初始化为列表:

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,然后用 连接字符串|以构建匹配所有键的正则表达式。生成的正则表达式非常有效。

这保证了字符串的每个部分只翻译一次。

于 2013-07-11T15:14:43.007 回答
3
%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 标志,正则表达式全局或重复应用于字符串,使用 e 标志替换表达式被评估为 perl 而不是文字替换

于 2013-07-11T15:10:53.850 回答
1

似乎有一个CPAN 模块可以执行此操作

于 2013-07-11T15:09:11.297 回答