从左到右解析阿拉伯语/RTL文本



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

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

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

‏‏‏‏‏spl[0]="‏测试:">
spl[1]="‏"اليوم
spl[2]=‏"a">
spl[3]=‏"b">

与原来的相比,上面的内容有点乱。相反,我希望得到这个:

‏‏spl[0]=‏"测试:اليوم">
spl[1]="‏اليفد">
spl[2]=‏"a">
spl[3]=‏"b">

我准备编写自己的分裂函数。然而,字符串中的字符也以相反的顺序进行解析,所以我回到了原点。我只想按屏幕上显示的方式浏览每个角色。

正如您的字符串当前所处的位置,单词"اليف"存储在单词"ا·ي"之前;事实上,اليوم显示为"第一个"(即,更左边),只是Unicode双向算法在显示文本时的(正确)结果。

也就是说:你开始的字符串("测试:اليفب;ايي1608;م;a;b")是用户输入"测试:",然后是لدي,然后是";",再是ال。因此,C#拆分它的方式实际上反映了创建字符串的方式。只是它的创建方式没有反映在字符串的显示中,因为两个连续的阿拉伯单词在显示时被视为一个单元。

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

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

static void Main(string[] args) {
string s = "Test:اليوم;u200Eلطيفة;a;b";
string[] spl = s.Split(';');
}

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

它们的字符串没有反转,但实际上是按正确的顺序拆分的。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。

根据Reflector的说法,Split内部使用Substring,并且使用了一个内部函数,该函数只从左到右复制字母,而不考虑区域性。正因为如此,我看不出任何方法可以仅仅反转Split返回的数组。

最新更新