我有这两个示例字符串:

$a=‘侏儒’; $B=‘侏儒’;

它们在视觉上看起来是一样的,但第三个字符不同:

在字符串$a上是Unicode 227(带波浪符号的拉丁文小写字母a),在字符串$b上是Unicode 97(拉丁文小写字母a)+Unicode 771(组合波浪符号)

如何检测字符串是否包含任何组合字符,而不是"常规"字符?

我try 用函数"order()"判断字符串中的所有字符,但没有成功.

推荐答案

请注意,ord在ASCII范围内运行,仅匹配单字节编码的字符,对0-255范围之外的多字节Unicode字符没有帮助.

如何匹配组合变音符号

您可以使用带有Unicode u标志的preg_match,然后匹配适当的Unicode字符范围.在这种情况下,\p{M}将完成这项工作.它代表:

\p{M}或\p{Mark}:要与另一个字符组合的字符(例如重音、元音、包围方框等).

适用范围如下:

$a = 'Anão';
$b = 'Anão';

var_dump([
    preg_match('~\p{M}~u', $a), // = 0
    preg_match('~\p{M}~u', $b) // = 1
]);

返回01:您的$b字符串有一个组合变音符号.然后,您将判断if(preg_match('~\p{M}~u', $str))以找出字符串是否包含组合变音符号.

这将匹配所有类型的组合变音符号.如果您想要确定组合元音变音符号所属的确切字符类别,它将在{Mn}的范围内:

\p{Mn}或\p{Non_Spacing_Mark}:在不占用额外空格的情况下与另一个字符组合的字符(如重音、变音等).

如何规范变音符号

如果你的问题源于"how do I make these strings equivalent",因为当$a != $b看起来一样的时候,显然是有问题的.PHP有一个方便的Normalizer类,用于将Unicode字符串转换为它们的canonical forms.用法如下:

Normalizer::normalize('Anão', Normalizer::NFC); // Single Char, Default
Normalizer::normalize('Anão', Normalizer::NFD); // Combined

在这里,NFC(默认)或Normalization Form C代表"Canonical Decomposition, followed by Canonical Composition",首先将字符拆分成几个部分,然后尽可能地组合成一个字符.同样,NFD,Normalization Form D (NFD)代表"Canonical Decomposition",其中变音符号变成单独的组合字符,等等.

如果您规范化了所有可能包含变音符号的字符串,无论是在源数据中还是在对其进行的查询中,我怀疑您最初的问题都不会出现.


附注:请参阅regular-expressions.info获取有用的Unicode reference for Regex小抄,以及维基百科上的Unicode character property / Categories表格.

Php相关问答推荐

PHP 8.3类型类常数-关闭

如何在Woocommerce中禁用机器人添加到推车?

WooCommerce在store 页面上显示兼容多语言的产品属性

在WooCommerce我的帐户部分添加带有自定义链接的自定义菜单项

根据产品类型显示或隐藏WooCommerce管理产品自定义字段

目标类[Set_Locale]不存在.拉威尔

允许在WooCommerce管理订单列表中使用计费邮箱进行搜索

如何在自定义邮箱内容中获取WooCommerce订单项目的详细信息?

计算添加到购物车的点击次数并将其显示在 WooCommerce 管理产品列表中

当我激活插件时出现错误注意:未定义的偏移量:1

向元素添加类时添加循环错误

使用 Laravel 和 Vue 进行图像表单验证

在 Botiga 主题模板中添加复选框到政策行.Woocommerce

如何设置Mailersend PHP API 模板变量?

如何在构建 PHP 类别数组树的递归函数中将父面包屑传递给子项?

NetBeans 不显示中文内容

WordPress 函数 get_post(post_id) 是否查询数据库?

使用 --exclude-dir 选项从 PHP 执行 grep 时出现问题

Google Drive - 仅使用 FileID 获取文件的 FileSize

升级到 PHP 8.2:ksort 和 krsort 更改