为什么比较两个相等的波斯单词不会返回0?

时间:2013-02-20 15:30:58

标签: c# .net vb.net cultureinfo culture

我们有两个相同的字母'ی'和'ي',第一个作为主要信件在Windows 7之后出现 回到旧版XP,我们将第二个作为主要版本 现在,如果一个客户端在Windows XP上,另一个客户端在Windows 7上,我得到的输入被确定为不同 我也尝试过使用波斯文化但没有成功 我错过了什么吗? 编辑:不得不改变单词以便更好地理解......现在它们看起来很相似。

foreach (CompareOptions i in Enum.GetValues(new CompareOptions().GetType()).OfType<CompareOptions>()) 
    Console.WriteLine( string.Compare("محسنين", "محسنین", new CultureInfo("fa-ir"), i) + "\t : " + i );

输出:

-1       : None
-1       : IgnoreCase
-1       : IgnoreNonSpace
-1       : IgnoreSymbols
-1       : IgnoreKanaType
-1       : IgnoreWidth
1        : OrdinalIgnoreCase
-1       : StringSort
130      : Ordinal

3 个答案:

答案 0 :(得分:5)

两个字符串相等。最后一个字母不同。

关于IgnoreCase为什么返回-1但OrdinalIgnoreCase返回1:

的原因
  • OrdinalIgnoreCase使用不变文化将字符串转换为高位,然后执行逐字节比较
  • IgnoreCase使用指定的区域性来执行不区分大小写的比较。

不同之处在于IgnoreCase更多地了解指定语言字母的差异,并且可能与不变文化的处理方式不同,导致不同的结果。
这是所谓的"The Turkish İ Problem"的不同表现形式。

您可以使用InvariantCulture而不是波斯语来自行验证:

foreach (CompareOptions i in Enum.GetValues(new CompareOptions().GetType()).OfType<CompareOptions>()) 
    Console.WriteLine( string.Compare("محسنی", "محسني", CultureInfo.InvariantCulture, i) + "\t : " + i );

这将为IgnoreCaseOrdinalIgnoreCase输出1。

关于您编辑过的问题:
两个字符串仍然不同。以下代码输出字符串中单个字符的值。

foreach(var value in strings.Select(x => x.ToCharArray().Select(y => (int)y)))
    Console.WriteLine(value);

结果如下:

1605
1581
1587
1606
1610 // <-- "yeh": ي
1606

1605
1581
1587
1606
1740 // <-- "farsi yeh": ی
1606

正如您所看到的,有一个字符不同,导致比较将这两个字符串视为不相等。

答案 1 :(得分:0)

这里我的代码字符阿拉伯语“ي,ك”到波斯语“ی,ک”,通过扩展方法:

 private static readonly string[] pn = { "ی", "ک" };
    private static readonly string[] ar = { "ي", "ك" };
    public static string ToFaText(this string strTxt)
    {
        string chash = strTxt;
        for (int i = 0; i < 2; i++)
            chash = chash.Replace(ar[i],pn[i]);
        return chash;
    }

答案 2 :(得分:0)

public string ToFaText(string strTxt)
{
    return strTxt.Replace("ك","ک").Replace("ي","ی");
}

用法:

        string str="اولين برداشت";
        string per = ToFaText(str);