如何将扩展拉丁字符更改为其非重音ASCII等效字符?

时间:2009-01-16 10:36:12

标签: regex perl

我需要一个通用的音译或替换正则表达式,它将扩展的拉丁字符映射到类似的ASCII字符,并将所有其他扩展字符映射到''(空字符串),以便...

  • é变为e

  • ê成为e

  • á成为

  • ç成为c

  • Ď成为D

等等,但是像‡或Ω或‰这样的东西只是被条纹化了。

5 个答案:

答案 0 :(得分:8)

使用Unicode :: Normalize获取NFD($ str)。在这种形式中,具有变音符号的所有字符将变成基本字符,然后是组合变音字符。然后只需删除所有非ASCII字符。

答案 1 :(得分:2)

也许CPAN模块可能有帮助吗?

Text::Unidecode看起来很有希望,但它不会剥离‡或Ω或‰。相反,它们被++,O和%o取代。这可能是也可能不是你想要的。

Text::Unaccent,是另一个候选人,但只是为了摆脱重音。

答案 2 :(得分:2)

Text::Unaccent或者Text::Unaccent::PurePerl听起来就像你要求的那样,至少是它的前半部分。

$unaccented = unac_string($charset, $string);

删除所有非ASCII字符会相对简单。

s/[^\000-\177]+//g;

答案 3 :(得分:1)

所有精彩的答案。但实际上没有一个真正奏效将扩展字符直接放在源代码中会导致在终端窗口或跨平台的各种代码/文本编辑器中工作时出现问题。我能够尝试使用Unicode :: Normalize,Text :: Unidecode和Text :: Unaccent,但是不能让他们中的任何一个完全按照我的意愿去做。

最后,我只列举了我想要为UTF-8音译的所有字符(这是我输入数据中最常见的代码页)。

我需要两个额外的替换来照顾æ和Æ我希望映射到两个字符

对于感兴趣的团体,最终的代码是:( tr是单行)

$word =~ tr/\xC0\xC1\xC2\xC3\xC4\xC5\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF
\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xE0\xE1\xE2\xE3\xE4
\xE5\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8
\xF9\xFA\xFB\xFC\xFD\xFF/AAAAAACEEEEIIIIDNOOOOOOUUUUYaaaaaaceeeeiiiionoo
oooouuuuyy/;
$word =~ s/\xC6/AE/g;
$word =~ s/\xE6/ae/g;
$word =~ s/[^\x00-\x7F]+//g;

由于类似于things不是UTF-8的一部分,因此在我的输入数据中几乎不会出现这种情况。对于非UTF-8输入,我选择放弃127以上的所有内容。

答案 4 :(得分:0)

当我想翻译一些字符串时,不仅仅是字符,我正在使用这种方法:

my %trans = (
  'é' => 'e',
  'ê' => 'e',
  'á' => 'a',
  'ç' => 'c',
  'Ď' => 'D',
  map +($_=>''), qw(‡ Ω ‰)
};

my $re = qr/${ \(join'|', map quotemeta, keys %trans)}/;

s/($re)/$trans{$1}/ge;

如果你想要一些更复杂的东西,你可以使用函数而不是字符串常量。通过这种方法,您可以做任何您想做的事情。但是对于你的案例tr应该更有效:

tr/éêáçĎ/eeacD/;
tr/‡Ω‰//d;