Я экспериментировал с многобайтовыми строками и как с ними обращаться. Используя код, который вы можете увидеть здесь
https://gist.github.com/charlydagos/89f67808e01f97e6de91
Мне удалось вращать большинство струн. Однако я заметил, что линия
$chr = mb_substr($str, $i, 1);
Не будет работать для флаг смайликов, поскольку они используют более одной кодовой точки Unicode.
Вы можете попробовать следующее в ваших собственных оболочках:
Это дает желаемый результат: $ php string_rotate_mb.php "你好"
Это однако $ php string_rotate_mb.php ""
возвращается [H][C]
Что технически правильно, это повернуло строку. Но на самом деле это один глиф, и моим желаемым выводом является только флаг (или последовательность флагов, которые затем становятся еще более искаженными глифами, иногда даже превращая его в другие флаги).
Как тогда я могу достоверно определить, что я должен взять $length = 1
или $length = 2
(или $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-8
, а также iTerm2: Build 2.9.git.8dff8db518
,
Решение: https://gist.github.com/charlydagos/6755ad994da07a7b4959#file-string_rotate_working-php-L39-L56
Спасибо Roeland за представление концепции графемных кластеров. Хорошая информация также в следующих ссылках
Есть еще много примеров, где это не удается:
Составление персонажей: сравнить ê а также ê (первый на самом деле U + 0302 и U + 0065)
Варианты: например. смайлики могут иметь черно-белый или цветной вариант «против». Это делается путем добавления вариант выбора после смайликов похожая проблема с этническими вариациями: . (примечание: поддержка этого немного нестабильна, но по крайней мере Windows 10 поддерживает эти варианты)
Флаги, которые состоят из двух кодовых точек.
Фракции, использующие черту Fraction (U + 2044), также могут отображаться с одним глифом. Например. 1/2. Обратите внимание на разницу с 1/2
И так далее…
Я думаю, что то, что вы ищете, называется кластерами графем. Без поддержки библиотеки я думаю, что это довольно сложно понять правильно.
Для последних версий PHP есть intl
расширение. Вы можете перебрать кластеры, используя функции графемы.
Других решений пока нет …