首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从换能器转换中排除特定字符

从换能器转换中排除特定字符
EN

Stack Overflow用户
提问于 2021-05-17 14:01:55
回答 5查看 478关注 0票数 3

我正在尝试使用PHP进行音译,但我需要的是所有非拉丁字符的转换,但要保持意大利语的重音字符。

PHP转写器缺乏文档和在线示例。我已经阅读了ICU医生,并且我知道有一条规则强制换能器将字符转换为我们指定的另一个字符(à > b)。

代码(使用create函数)

代码语言:javascript
复制
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$transliterator = Transliterator::create("Any-Latin; Latin-ASCII");
echo $transliterator->transliterate($str);

将所有非拉丁字符转换为拉丁语(带有所有重音字符),并给出结果。

代码语言:javascript
复制
ASAaeiou Chen Hai yao Munchen Faisst Finis guo nei - jing xiang

和代码(使用createFromRules函数)

代码语言:javascript
复制
$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,给出了结果。

代码语言:javascript
复制
AŠAbèìòù Chén Hǎi ybo München Faißt Финиш 国内 - 镜像

因此,我的目标是将Any-Latin; Latin-ASCII转换与à > à规则(以及其他意大利语重音元音)合并,以便告诉音译者将所有非拉丁语字符转换为拉丁语,但将意大利语重音元音转换为自己,结果如下:

代码语言:javascript
复制
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang

是否有方法将à>à规则放置在create函数的参数中,或者在createFromRules函数的参数中添加Any-Latin; Latin-ASCII指令?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2021-07-10 18:33:48

给出输入和输出的示例:

代码语言:javascript
复制
$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";
代码语言:javascript
复制
ASAaeiou Chen Hai yao Munchen Faisst Finis guo nei - jing xiang

当仅将音译应用于与您指定的字符范围不匹配的片段时(意大利语重音字符àè下同),它应该提供结果。

一种选择是使用preg_replace_callback

它需要回调才能应用音译:

代码语言:javascript
复制
$transliterate = static function (array $match) use ($transliterator) {
    return $transliterator->transliterate($match[0]);
};

它需要有一个模式来匹配所有的东西,除了要保留的字符。它需要正确定义并与Unicode兼容:

代码语言:javascript
复制
([^\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模式兼容:

代码语言:javascript
复制
echo preg_replace_callback(
    '([^\xE0\xE8\xEC\xF2\xF9]+)ui', 
    $transliterate, 
    Normalizer::normalize($str, Normalizer::NFC)
), "\n";

产出:

代码语言:javascript
复制
ASAàèìòù Chen Hai yao Munchen Faisst Finis guo nei - jing xiang

跨PHP版本的示例

增编:

  • 意大利重音字符的\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字符与十六进制代码hhh. }字符与十六进制代码hhh.
  • 链接到完整的PCRE语法:https://www.pcre.org/original/doc/html/pcresyntax.html
票数 1
EN

Stack Overflow用户

发布于 2021-07-10 09:54:10

您可以使用preg_replace_callback过滤除意大利语重音字符以外的所有字符,并在其上应用音译。

票数 1
EN

Stack Overflow用户

发布于 2021-05-17 17:39:40

您所要做的就是删除Latin-ASCII规则。

代码语言:javascript
复制
$str = "AŠAàèìòù Chén Hǎi yáo München Faißt Финиш 国内 - 镜像";
$transliterator = Transliterator::create("Any-Latin; Any-NFC");
echo $transliterator->transliterate($str);

输出:

代码语言:javascript
复制
AŠAàèìòù Chén Hǎi yáo München Faißt Finiš guó nèi - jìng xiàng

您还可能希望利用此机会对字符串应用规范化规则,以便根据您计划如何处理重音字符,将重音字符组成或分解为一致的形式。

代码语言:javascript
复制
$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)
);

输出:

代码语言:javascript
复制
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,创建具有复杂组合的“重复”文件,这是很难处理的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67571235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档