如何水平翻转文字?

Ian*_*oyd 5 unicode text text-processing localization right-to-left

我需要编写一个从左到右翻转字符串的所有字符的函数.

例如:

译文:你好.

应该成为

.goȡyzⱥlëhtrểvoᶁềṕmujxofnworḇkçiuqėhT

我可以将问题限制在UTF-16(与UTF-8有相同的问题,只是不那么频繁).

天真的解决方案

一个天真的解决方案可能会尝试翻转所有的东西(例如,逐字逐句,其中一个字是16位 - 如果我们假设一个字节是16 位,我会说字节为字节.我也可以说字符-for-character其中characterChar表示单个代码点的数据类型):

String original = "??f???r??n?t";
String flipped = "";
foreach (Char c in s)
{
   flipped = c+fipped;
}
Run Code Online (Sandbox Code Playgroud)

导致错误翻转文本的结果:

  • ??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语言平面问题,但不能解决组合变音符问题

bob*_*nce 3

您要查找的术语是 \xe2\x80\x9cgrapheme cluster\xe2\x80\x9d,如 Unicode TR29 Cluster Boundaries中定义。

\n\n

使用代理算法(简单)将 UTF-16 代码单元分组为 Unicode 代码点(=字符),然后使用 Grapheme_Cluster_Break 规则将字符分组为字素簇。最后颠倒小组顺序。

\n\n

您将需要 Unicode 字符数据库的副本才能识别字素簇边界。这已经占用了大量的空间,因此您可能需要一个库来完成它。例如,在 ICU 中,您可能会使用 CharacterIterator(该名称具有误导性,因为它适用于字素簇,而不是 Unicode 所知道的 \xe2\x80\x98characters\xe2\x80\x99)。

\n