可靠地旋转任何琴弦

Reliably rotating any string

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

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

我成功地旋转了大多数琴弦。但是我注意到那行

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

不适用于 flag emojis,因为它们使用多个 unicode 代码点。

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

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

这不过$ php string_rotate_mb.php ""returns[H][C]

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

那么,我如何可靠地确定我应该使用 mb_substr 获取 $length = 1$length = 2(或 $length = N)子字符串?

作为参考,我使用了 PHP 7.0.2 (cli) (built: Jan 7 2016 10:40:26) ( NTS )ZSH_VERSION = 5.2LC_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 介绍字素簇的概念。以下链接中也有很好的信息

还有很多失败的例子:

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

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

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

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

  • 的区别

等等……

我想你要找的是所谓的字素簇。如果没有图书馆的支持,我认为这很难做到。

最近的 PHP 版本有 intl 扩展。您可以使用 the grapheme functions.

遍历集群