0

我正在试验多字节字符串以及如何处理它们。使用您可以在此处看到的代码

https://gist.github.com/charlydagos/89f67808e01f97e6de91

我成功地旋转了大多数琴弦。但是我注意到这条线

$chr = mb_substr($str, $i, 1);

不适用于标志表情符号,因为它们使用多个 unicode 代码点。

您可以在自己的 shell 中尝试以下操作:

这给出了所需的输出:$ php string_rotate_mb.php "你好"

然而,这会$ php string_rotate_mb.php ""返回[H][C]

这在技术上是正确的,它确实旋转了字符串。但实际上它是单个字形,我想要的输出是单独的标志(或一系列标志,然后变成更加乱码的字形,有时甚至将其变成不同的标志)。

那么,我怎样才能可靠地确定我应该使用 a$length = 1或 a $length = 2(或 a $length = N)获取子字符串mb_substr

作为参考,我使用PHP 7.0.2 (cli) (built: Jan 7 2016 10:40:26) ( NTS ), ZSH_VERSION = 5.2,LC_ALL=en_us.utf-8iTerm2: Build 2.9.git.8dff8db518.

更新 - 2016 年 2 月 5 日

解决方案:https ://gist.github.com/charlydagos/6755ad994da07a7b4959#file-string_rotate_working-php-L39-L56

感谢roeland介绍 Grapheme Clusters 的概念。以下链接中也有很好的信息

4

1 回答 1

1

还有很多失败的例子:

  • 组成字符:比较êê(第一个实际上是U+0302和U+0065)

  • 变体:例如。表情符号可以有黑色/白色或颜色变体︎ vs ️。这是通过在表情符号后添加变体选择器来完成的。种族差异的类似问题:。(注意:对此的支持有点参差不齐,但至少 Windows 10 支持这些变体)

  • 标志,由两个代码点组成。

  • 使用分数破折号 (U+2044) 的分数也可以用一个字形呈现。例如。1⁄2 . 注意与1/2的区别

等等……</p>

我认为您正在寻找的是所谓的字形簇。如果没有图书馆的支持,我认为这很难做到。

对于最近的 PHP 版本,有intl扩展。您可以使用字形函数遍历集群。

于 2016-02-04T21:20:53.810 回答