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

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个回答

13

根据你的字符串,单词“لطيفة”存储在单词“اليوم”之前;显示为“首位”的事实(也就是说,向左更远),只是Unicode双向算法在显示文本时的一个(正确)结果。

这意味着:你开始使用的字符串("Test:لطيفة;اليوم;a;b")是用户先输入"Test:",然后是لطيفة,";",然后是اليوم,最后是";a;b"的结果。因此,C#对其进行拆分的方式确实反映了字符串创建的方式。只是创建方式不反映在字符串的显示上,因为两个连续的阿拉伯语单词在显示时被视为一个单元。

如果您希望字符串按从左到右的顺序显示阿拉伯语单词,并在其中加入分号,同时保持单词在同样的顺序存储,则应在分号后添加从左到右标记(U+200E)。这将有效地将每个阿拉伯语单词分开作为自己的单元,双向算法将分别处理每个单词。

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

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

谢谢!现在一切都清楚了。是的,我犯了一个错误,认为显示器显示的是“正确”的(从我的角度来看)。\u200e不会改变它的内部存储方式,只会改变它的显示方式。我保存了看似不正确的 CSV 文件(其中数据出现在错误的列标题下),将其加载到 Excel 中,每个单元格中的数据都位于正确的标题下!我只需要小心使用 U+200E 字符,因为我必须将其限制为与 RTL 字符相邻,如其他地方所述。我希望 Unicode/VS 在这些情况下将 \u200E 方式作为默认样式。 - Dan W

2
你也可以使用微软的Uniscribe库。ScriptItemize方法会给出字符簇、它们在原始字符串中的起始索引和RTL顺序。利用这些信息,你可以找到仅包含阿拉伯语的连续簇。根据 ';' 进行分割并反转方向,就能得到你需要的内容。

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。


以防我误解了您的意思,我想要翻转的不是每个字符串内部的内容,而是字符串本身的顺序。不幸的是,我仍然需要从左到右解析,以保持与CSV中可能存在的从左到右文本的兼容性。 - Dan W
如果你反转字符串本身,你会得到反转的单词,这些单词没有任何意义。Ibra和Arbi不是同一件事,aibrala甚至不是一个单词。 - zmbq
是的,我不想翻转任何字符串本身,只是想要翻转标记的顺序。 - Dan W
我进一步编辑了我的问题(并缩短了它),这样你就可以看到更深层次的问题。让我知道你的想法。感谢你的帮助。 - Dan W
你可以根据任意非字母数字的字符分割字符串,然后正确地组合和整理这些部分(如果是逗号,则反转顺序;如果不是,则直接组合)。这很难搞定。最好的方法是让用户按照正确的顺序将字符串输入到Excel中。不要陷入右到左的问题中,否则会出现无数个错误。 - zmbq
谢谢你的警告。我同意自己尝试修复可能会浪费大量时间(仅仅看一眼Unicode双向算法就足以让我噩梦连连)。不幸的是,如果你拿一个阿拉伯语的vCard来说,就会出现这个问题,即英文后面跟着阿拉伯文本,然后再跟着一些英文。这在第一次是“正确”的,但在我尝试解析它时就不是了。 - Dan W

0
据Reflector显示,Split内部似乎使用Substring,而后者又使用一个内部函数,该函数只是从左到右复制字母而没有考虑任何文化因素。因此,我认为没有其他方法,只能颠倒 Split 返回的数组。

谢谢。问题出现在CSV中还有使用“正常”LTR格式的文本。因此,如果我反转数组,那么包含“正常”文本的字符串的顺序也会被反转。我可以逐个字符地解析它,但问题仍然存在,因为从RTL解析文本时,文本也是RTL的。 - Dan W
修改了我的问题以澄清问题。 - Dan W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接