如何解决从音译转换中排除特定字符
我正在尝试使用 PHP 进行音译,但我需要的是转换所有非拉丁字符,但保留意大利重音字符 (àèìòù)。
PHP Transliterator 缺少文档和在线示例。
我已经阅读了 ICU docs 并且我知道有一条规则会强制 Transliterator 将一个字符转换为我们指定的另一个字符 (à > b
)。
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$transliterator = Transliterator::create("Any-Latin; Latin-ASCII");
echo $transliterator->transliterate($str);
将所有非拉丁字符转换为拉丁字符(带有所有重音字符)并给出结果
ASAaeIoU Chen Hai yao Munchen Faisst Finis guo nei - jing xiang
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$transliterator = Transliterator::createFromrules("á>b");
echo $transliterator->transliterate($str);
强制正确地将 à
转换为 b
,但是,显然,没有由前面的代码进行的转换 Any-Latin; Latin-ASCII
,给出结果
AŠAbèìòù Chén Hǎi ybo München Faißt Финиш 国内 - 镜像
所以我的目标是合并 Any-Latin; Latin-ASCII
转换和 à > à
规则(以及其他意大利语重音元音),以便告诉 Transliterator 将所有非拉丁字符转换为拉丁字符,但将意大利语转换为重读元音,结果如下:
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang
有没有办法将 à>à
规则放在 create
函数的参数中或在 Any-Latin; Latin-ASCII
函数的参数中添加 createFromrules
指令?
解决方法
您可以使用 preg_replace_callback
过滤除意大利语重音字符之外的所有字符并对其应用音译。
以输入和输出为例:
$transliterator = Transliterator::create("Any-Latin; Latin-ASCII");
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
echo $transliterator->transliterate($str),"\n";
ASAaeiou Chen Hai yao Munchen Faisst Finis guo nei - jing xiang
当仅对与您指定保留的字符范围(意大利重音字符 [àèìòù])不匹配的段应用音译时,它应该提供结果。
一种选择是使用 preg_replace_callback
。
应用音译需要回调:
$transliterate = static function (array $match) use ($transliterator) {
return $transliterator->transliterate($match[0]);
};
而且它需要有一个模式来匹配除要保留的字符之外的所有内容。它需要正确定义并与 Unicode 兼容:
([^\xE0\xE8\xEC\xF2\xF9]+)ui
(...) : delimiters: the regular expression is inside
u : modifier: u - Unicode mode (UTF-8 encoding in
PHP,PCRE_UTF8)
i : modifier: i - letters in the pattern match
both upper and lower case letters
(PCRE_CASELESS)
[^...] : character class: not matching any of the
characters (`^`); negated character class
\xE0\xE8\xEC\xF2\xF9 : the italian accented characters àèìòù written
in a stable notation (you can easily copy and
paste it for example)
最后但并非最不重要的一点是,要操作的对象必须与要保留的字符兼容。由于在 Unicode 中可以有多种方法来编写相同的字符,因此输入被规范化以与 PCRE 模式兼容:
echo preg_replace_callback(
'([^\xE0\xE8\xEC\xF2\xF9]+)ui',$transliterate,Normalizer::normalize($str,Normalizer::NFC)
),"\n";
输出:
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang
附录:
-
\xE0\xE1\xE8\xE9\xEC\xED\xF2\xF3\xF9\xFA
意大利语重音字符的小写列表(可与 i 修饰符一起使用) -
\xC0\xC1\xC8\xC9\xCC\xCD\xD2\xD3\xD9\xDA\xE0\xE1\xE8\xE9\xEC\xED\xF2\xF3\xF9\xFA
意大利语重音字符的小写和大写列表(可以在没有 i 修饰符的情况下使用) - PCRE 语法字符(摘录):
\xhh character with hex code hh \x{hhh..} character with hex code hhh..
- 链接到完整的 PCRE 语法:https://www.pcre.org/original/doc/html/pcresyntax.html
您所要做的就是删除 Latin-ASCII
规则。
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$transliterator = Transliterator::create("Any-Latin; Any-NFC");
echo $transliterator->transliterate($str);
输出:
AŠAàèìòù Chén Hǎi yáo München Faißt Finiš guó nèi - jìng xiàng
您可能还想借此机会对字符串应用规范化规则,以将重音字符组合或分解为一致的形式,具体取决于您打算对它们做什么。
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$none = Transliterator::create("Any-Latin");
$nfc = Transliterator::create("Any-Latin; Any-NFC");
$nfd = Transliterator::create("Any-Latin; Any-NFD");
var_dump(
$none->transliterate($str),$nfc->transliterate($str),$nfd->transliterate($str)
);
输出:
string(78) "AŠAàèìòù Chén Hǎi yáo München Faißt Finiš guó nèi - jìng xiàng"
string(78) "AŠAàèìòù Chén Hǎi yáo München Faißt Finiš guó nèi - jìng xiàng"
string(93) "AŠAàèìòù Chén Hǎi yáo München Faißt Finiš guó nèi - jìng xiàng"
NFC 是“组合式”的,因为在所有具有单码点表示的重音字符中都是这样表示的。 NFD 被“分解”,所有重音字符都被拆分为它们的基本代码点和一个重音组合标记。在这两种情况下,单个基字符上的多个组合标记将以一致的方式排列。
有些文件系统需要某种形式,例如:Mac 需要 NFD,而有些文件系统会简单地接受任何东西,例如:ext,创建难以处理的混合组合的“重复”文件。
,我在尝试避免不需要的音译时使用的一种方法 - 它有点丑陋,但工作量很小。用标签代替你不想音译的字符,然后在音译后替换它们:
<?php
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$str = str_replace(['à','è','ì','ò','ù'],['@@a@@','@@e@@','@@i@@','@@o@@','@@u@@'],$str);
$transliterator = Transliterator::create("Any-Latin; Latin-ASCII");
$out = $transliterator->transliterate($str);
$out = str_replace(['@@a@@',['à',$out);
echo $out;
结果是:
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。