如何水平翻转文字?

时间:2012-01-24 15:48:50

标签: text unicode localization text-processing right-to-left

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

e.g:

  

Thêquiçkḇrownfoxjumṕềᶁovểrthëlⱥzyȡog。

应该成为

  

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

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

天真的解决方案

一个天真的解决方案可能会尝试flip all the things(例如,逐字逐句,其中一个字是16位 - 如果我们可以假设a,我会说 byte for byte 字节是16位。我也可以说 character-for-character 其中字符是表示单个代码点的数据类型Char:< / p>

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 ˘ ę {{ 1}} n i t

并翻转每个“代码点”给出:

  • ˛ ˛ t i n ę ˘ r ế {{ 1}} ˜ f

这不仅是有效的UTF-16编码,也不是相同的字符。

失败

当存在:

时,问题出现在UTF-16编码中

这些相同的问题在UTF-8编码中发生,附加案例

  • 0..127 ASCII范围之外的任何字符

我可以将自己局限于更简单的UTF-16编码(因为那是我正在使用的语言的编码(例如C#,Delphi)

在我看来,问题在于发现一些后续的代码点是否正在组合字符,并且需要附带基本字形。

观看online text reverser site未能将此考虑在内也很有趣。

  

注意:

     
      
  • 任何解决方案都应该假设无法访问UTF-32编码库(主要是因为我无法访问任何UTF-32编码库)
  •   
  • 访问UTF-32编码库可以解决UTF-8 / UTF-16语言平面问题,但不能解决组合变音符号问题
  •   

3 个答案:

答案 0 :(得分:3)

您正在寻找的术语是“字形集群”,如Unicode TR29 Cluster Boundaries中所定义。

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

您需要Unicode字符数据库的副本才能识别字形集群边界。这已经占用了相当大的空间,所以你可能想要一个库来做它。例如,在ICU中,您可能会使用CharacterIterator(由于它在字形集群上工作而误导性地命名,而不是Unicode知道它的'字符'。)

答案 1 :(得分:2)

如果您使用UTF-32,则可以解决非基准平面问题。从UTF-8或UTF-16转换为UTF-32(以及返回)是相对简单的比特(参见维基百科)。你没有必要的库。

大多数组合字符都在几个范围内。您可以通过扫描Unicode数据库来确定这些范围(请参阅Unicode.org)。将这些范围硬编码到您的应用程序中这样,您就可以确定代表单个字符的代码点组。 (缺点是将来可能会引入新的组合标记,您需要更新表格。)

适当分段,反转顺序(逐段),然后转换回UTF-8或UTF-16(或任何你想要的)。

答案 2 :(得分:-1)

Text Mechanic的Text Generator似乎是在JavaScript中执行此操作。我确信在获得作者的同意后,可以将JS翻译成另一种语言(如果你能找到该网站的'联系'链接)。