我正在尝试使用PHP进行音译,但我需要的是所有非拉丁字符的转换,但要保持意大利语的重音字符。
PHP转写器缺乏文档和在线示例。我已经阅读了ICU医生,并且我知道有一条规则强制换能器将字符转换为我们指定的另一个字符(à > b)。
代码(使用create函数)
$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和代码(使用createFromRules函数)
$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转换与à > à规则(以及其他意大利语重音元音)合并,以便告诉音译者将所有非拉丁语字符转换为拉丁语,但将意大利语重音元音转换为自己,结果如下:
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang是否有方法将à>à规则放置在create函数的参数中,或者在createFromRules函数的参数中添加Any-Latin; Latin-ASCII指令?
发布于 2021-07-10 18:33:48
给出输入和输出的示例:
$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-修饰符)发布于 2021-07-10 09:54:10
您可以使用preg_replace_callback过滤除意大利语重音字符以外的所有字符,并在其上应用音译。
发布于 2021-05-17 17:39:40
您所要做的就是删除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,创建具有复杂组合的“重复”文件,这是很难处理的。
https://stackoverflow.com/questions/67571235
复制相似问题