加入混合的从右到左和从左到右的语言字符串的奇怪行为

如何解决加入混合的从右到左和从左到右的语言字符串的奇怪行为

输入:

临时文本数组: ▿ 3个要素

- 0 : "זה מבחן"
- 1 : "7 x 5 abc"
- 2 : "other text"

在执行简单的 tempText = tempTextArray.joined(" | ") 时,结果并未将所有元素放置在我期望的位置...结果:

Printing description of tempText:
"זזה מבחן | 7 x 5 abc | other text"

这是我第一次结合从右到左和从左到右的文本,以前有没有人处理过类似的情况?

我的应用正在接收来自后端的翻译,所以我不知道哪些元素被翻译成(在这种情况下)希伯来语,以及我将以我的认语言(英语)接收哪些元素

解决方法

这是由 Unicode BIDI (Bidirectional Text) algorithm 引起的。首先,我将解释如何修复它,因为它相当简单,然后我将解释发生了什么,以防您需要更多信息。

您需要在每个要将文本方向重置为 LTR 的位置添加 LTR(从左到右标记)字符。在您的情况下,它位于字符串的开头和每个 | 块的开头:

let ltr = "\u{200e}"
let tempText = ltr + tempTextArray.joined(separator: "\(ltr) | ")
// => ‎זה מבחן‎ | 7 x 5 abc‎ | other text

如果您打算使用希伯来语,您绝对想阅读 Cal Henderson 对算法的精彩解释:Understanding Bidirectional (BIDI) Text in Unicode

现在来解释发生了什么。您正在打印一个字符串,其第一个字符是“זה מבחן”中的 ז,最后一个字符是“text”中的最后一个 t。它不是由 | 分隔的三个字符串,它只是一个长字符串。当您显示该字符串时,BIDI 算法必须决定所有字符的位置。

第一个字符 (ז) 是一个 RTL 字符,因此它决定这是一个嵌入了一些 LTR 文本的 RTL 字符串。这与你想要的相反。您希望这是一个嵌入了一些 RTL 文本的 LTR 字符串。所以你需要从一个 LTR 字符开始,比如 Left-To-Right Mark。

BIDI 算法的工作是告诉系统下一个字符应该去哪个方向。 זה 中的每个字符都是 RTL,所以很简单,继续向左走。但是 זה 和 מבחן 之间的空间呢?空格在方向上是中性的,最后一个字符是 RTL,所以空格向左。但是接下来我们来到了 מבחן 和 | 之间的空间。空间是中性的和|是中性的,所以 BIDI 算法会把空格和 |再次向左。你想要空间和|要成为 LTR,所以你需要在那里添加另一个 LTR 字符。

7 也是中性的,但 x 是 LTR 的 LATIN SMALL LETTER X(不是 MULTIPLICATION X,它是中性的)。

最终结果是 BIDI 算法决定这是一个以 7 | זה מבחן 开头的 RTL 字符串,然后(向左)跟随一个嵌入的 LTR 字符串 x 5 abc | other text。 (换句话说,这是一个碰巧有一些英语的希伯来语字符串,而不是一个碰巧有一些希伯来语的英语字符串。)

我希望上述问题中实际显示的内容与您所看到的不同(因为 BIDI 算法是如何应用于 Stack Overflow 的)。我希望它实际上看起来像这样:

Embedded LTR string in a RTL string

如果您从右到左阅读本文,那么现在发生的事情应该更有意义。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?