Как перевернуть текст по горизонтали? - PullRequest
5 голосов
/ 24 января 2012

Мне нужно написать функцию, которая будет переворачивать все символы строки слева направо.

например:.

Быстрая лисица, играющая над собой.

должно стать

.goȡ yzⱥl ëht rểvo ᶁềṕmuj xof nworḇ kçiuq hhT

Я могу ограничить вопрос UTF-16 (который имеет те же проблемы, что и UTF-8, но реже).

Наивный раствор

Наивное решение может попытаться перевернуть все вещи (например, слово в слово, где слово 16-битное - я бы сказал байт для байта , если бы мы могли предположить, что байт был 16-битным. Я мог бы также сказать символ для символа где символ является типом данных Char, который представляет собой одну кодовую точку):

String original = "ɗỉf̴ḟếr̆ęnͥt";
String flipped = "";
foreach (Char c in s)
{
   flipped = c+fipped;
}

Результат неверно перевернутого текста:

  • ɗỉf̴ḟếr̆ęnͥt
  • ̨tͥnę̆rếḟ̴fỉɗ

Это потому, что один «символ» занимает несколько «кодовых точек».

  • ɗỉf̴ḟếr̆ęnͥt
  • ɗ f ˜ ế r ˘ ę n i t ˛

и переключение каждой «кодовой точки» дает:

  • ˛ t i n ę ˘ r ế ˜ f ɗ

Это не только недопустимая кодировка UTF-16, это не те же символы.

Отказ

Проблема возникает в кодировке UTF-16 при наличии:

Те же проблемы возникают в кодировке UTF-8, с дополнительным регистром

  • любой символ вне диапазона 0.127 ASCII

я могу ограничиться более простой кодировкой UTF-16 (поскольку это кодировка, которую использует язык, который я использую (например, C #, Delphi)

Проблема, как мне кажется, заключается в обнаружении, если ряд последующих кодовых точек объединяет символы и должен сопровождаться базовым глифом.

Также интересно наблюдать за тем, как сайт онлайн-реверсирования текста не принимает это во внимание.

Примечание:

  • любое решение должно предполагать, что не имеет доступа к библиотеке кодирования UTF-32 (в основном потому, что у меня нет доступа к какой-либо библиотеке кодирования UTF-32)
  • доступ к библиотеке кодирования UTF-32 решит проблему языковых плоскостей UTF-8 / UTF-16, но не проблему объединяющих диакритических знаков

Ответы [ 3 ]

3 голосов
/ 25 января 2012

Вы ищете термин «кластер графем», как определено в Unicode Границы кластера TR29 .

Сгруппируйте кодовые единицы UTF-16 в кодовые точки Unicode (= символы), используя суррогатный алгоритм (легко), затем сгруппируйте символы в кластеры графем, используя правила Grapheme_Cluster_Break. Наконец, измените порядок групп.

Вам потребуется копия базы данных символов Unicode, чтобы распознать границы кластера графем. Это уже займет много места, так что вы, вероятно, захотите получить библиотеку для этого. Например, в ICU вы можете использовать CharacterIterator (который вводит в заблуждение, так как он работает на кластерах графем, а не на «символах», как это знает Unicode).

2 голосов
/ 24 января 2012

Если вы работаете в UTF-32, вы решаете проблему не базовой плоскости.Преобразование из UTF-8 или UTF-16 в UTF-32 (и обратно) - это относительно простое переключение битов (см. Википедию).Вам не нужно иметь библиотеку для этого.

Большинство комбинирующих символов находятся в нескольких диапазонах.Вы можете определить эти диапазоны путем сканирования базы данных Unicode (см. Unicode.org).Закрепите эти диапазоны в вашем приложении.При этом вы можете определить группы кодовых точек, которые представляют один символ.(Недостатком является то, что в будущем могут быть введены новые метки объединения, и вам необходимо обновить таблицу.)

Сегментируйте соответствующим образом, измените порядок (сегмент за сегментом) и преобразуйте обратно в UTF-8 или UTF-16 (или как хотите).

0 голосов
/ 09 апреля 2013

Text Mechanic's Text Generator , кажется, делает это в JavaScript. Я уверен, что можно было бы перевести JS на другой язык после получения согласия автора (если вы можете найти ссылку «контакт» для этого сайта).

...