7

假设我有一个 RTL 语言的字符串,例如阿拉伯语,其中包含一些英语:

string s = "Test:لطيفة;اليوم;a;b"

注意字符串中有分号。当我使用 Split 命令string[] spl = s.Split(';');时,一些字符串以相反的顺序保存。这就是发生的事情:

‏‏‏‏ spl[0] = "‏Test:لطيفة"
spl[1] = "‏"اليوم
spl[2] = ‏"a"
spl[3] = ‏"b"

以上与原版相比,是乱七八糟的。相反,我希望得到这个:

‏‏spl[0] = ‏"Test:اليوم"
spl[1] = "‏لطيفة"
spl[2] = ‏"a"
spl[3] = ‏"b"

我准备编写自己的拆分函数。但是,字符串中的字符也以相反的顺序解析,所以我回到第一方。我只想浏览屏幕上显示的每个字符。

4

4 回答 4

13

正如您的字符串当前所显示的那样,单词 لطيفة 存储在单词 اليوم 之前;اليوم“首先”显示(即更靠左)的事实只是Unicode双向算法在显示文本时的(正确)结果。

即:您以 ("Test:لطيفة;اليوم;a;b") 开头的字符串是用户输入“Test:”,然后是 لطيفة,然后是“;”,然后是 اليوم,然后是“;a;”的结果。乙”。因此,C# 拆分它的方式实际上反映了创建字符串的方式。只是它的创建方式并没有体现在字符串的显示上,因为两个连续的阿拉伯语单词在显示时被视为一个单元。

如果您希望字符串以从左到右的顺序显示阿拉伯语单词,中间有分号,同时也以相同的顺序存储单词,那么您应该在后面加上一个从左到右的标记 (U+200E)分号。这将有效地将每个阿拉伯语单词划分为自己的单元,然后双向算法将分别处理每个单词。

例如,以下代码以与您使用的字符串相同的字符串开头(添加了一个从左到右的标记),但它会根据您期望的方式将其拆分(即, spl[0] = ‏"Test:اليوم", 和 spl[1] = "‏لطيفة"):

static void Main(string[] args) {
    string s = "Test:اليوم;\u200Eلطيفة;a;b";
    string[] spl = s.Split(';');
}
于 2012-10-01T22:29:07.287 回答
2

您还可以使用 Microsoft 的 Uniscribe 库。ScriptItemize 方法将为您提供字符簇、它们在原始字符串中的起始索引和 RTL 顺序。使用此信息,您可以找到仅包含阿拉伯语的连续聚类。将它们拆分为';' 并扭转方向会给你你所需要的。

于 2012-10-02T11:25:48.817 回答
1

它们的字符串没有颠倒,但实际上以正确的顺序拆分。RTL 语言在显示时是 RTL,但在内存中它们像英语一样保持“从左到右”。我将尝试演示,这有点困难,因为我没有安装阿拉伯语键盘。

你的字符串是s = "Arbi/Arbi, Alarbia". s[0] 是 A(阿拉伯语 A'in),s[1] 是 R,依此类推。s[4] 是 /,s[9] 是 , 。因此,在拆分时,您会在第一部分获得 s[0:8],在第二部分获得 s[10:]。

这是处理 RTL 字符串的正确方法。如果你想要反转,你需要自己反转数组。

请记住,在 RTL 和 LTR 之间切换是最令人沮丧的任务之一。您不知道要花多长时间弄清楚如何处理 RTL 字符串中的数字或英文单词。您可以做的最好的事情是完全避免该问题,并尝试让 Excel 将字符串显示为 RTL。

于 2012-09-27T22:07:14.567 回答
0

它看起来(根据 Reflector)在Split内部使用Substring并且使用内部函数,该函数只是从左到右复制字母,而不考虑文化。正因为如此,我看不出有任何办法只是反转Split返回的数组。

于 2012-09-27T22:04:20.480 回答