【问题标题】:String comparison in .Net: "+" vs "-".Net 中的字符串比较:“+”与“-”
【发布时间】:2010-02-11 12:51:57
【问题描述】:

我一直认为 .Net 根据当前文化按字典顺序比较字符串。但是当其中一个字符串以'-'结尾时会出现一些奇怪的情况:

"+".CompareTo("-")
Returns: 1

"+1".CompareTo("-1")
Returns: -1

我得到了我尝试过的所有文化,包括不变的文化。 谁能解释发生了什么,我怎样才能获得当前语言环境的一致的逐字符顺序?

【问题讨论】:

  • "x+".CompareTo("x-")"x+1".CompareTo("x-1") 相同

标签: c# .net string compare


【解决方案1】:

尝试将其更改为

string.Compare("+", "-", StringComparison.Ordinal); // == -2
string.Compare("+1", "-1", StringComparison.Ordinal); // == -2

【讨论】:

  • 谢谢 Anton,但 Ordinal 表示旧的良好 ASCII 排序,所有大写字母排在小写字母之前。 string.Compare("a", "Z", StringComparison.Ordinal); 7 在我的语言环境中,区分大小写的顺序类似于'a'
  • jmster:为什么不编写自己的排序?你只关心数字吗?
  • 我已经编写了自己的方法,但是在底部我需要一些方法来根据当地规则比较字符。而且我不想手动编写语言环境,应该可以从 Windows 获取它
【解决方案2】:

对于任何特定的语言环境,不一定有一个一致的逐个字符的顺序

来自MSDN documentation

例如,一种文化可以指定某些字符组合 被视为单个字符,或大写和小写字符 以特定的方式进行比较,或者说一个字符的排序顺序 取决于它前面或后面的字符。

确保逐个字符顺序一致的唯一方法是使用序号比较,如 Anton's answer 中所示。

【讨论】:

  • 这说明了问题。我唯一想知道的是,为什么他们需要为通用字符(如 ASCII 减号)引入这种神奇的处理方式?
  • @jmster:我的猜测是 +- 字符并没有真正孤立地表示任何东西,所以在这种情况下,在 + (代码 43)处进行序数比较计算结果为“小于”-(代码 45)。但是,当 +- 字符作为数字前缀时,它们就具有意义,在这种情况下,当 +1 大于 -1 时会发生“语义”和/或数字比较。跨度>
  • 其实恰恰相反,.NET 使用 ASCII 排序来得出“+1”小于“-1”的结论,但是在最后的位置,减号神奇地变成了连字符,所以“-”排序在“\a”(铃铛)和“”(空格)之间的某个位置。
  • @jmster:是的,你是对的。我的猜测是错误的。我认为文档的摘录仍然适用,但我不知道在这种情况下,不同的比较适用于什么特定逻辑。
【解决方案3】:
        string.Compare("+", "-");
        string.Compare("+", "-", StringComparison.CurrentCulture);
        string.Compare("+", "-", StringComparison.InvariantCulture);
        string.Compare("+", "-", StringComparison.InvariantCultureIgnoreCase);

        // All Pass

这两个值相等,因为考虑了 inguisitic 套管

修复:

将不变比较替换为序数比较。这意味着决策基于简单的字节比较,并忽略由文化参数化的大小写或等价表。

参考:Use ordinal StringComparison

string.Compare("+", "-", StringComparison.Ordinal); //失败

【讨论】:

    【解决方案4】:

    您可能希望使用真正的减号,Unicode 代码点 \u2212。您在编程中使用的减号 (\u002d) 是“连字符减号”,它的排序顺序是上下文相关的,因为它也经常用作连字符。 this article 中的许多不同类型的破折号比您想知道的要多。

    【讨论】:

    • 您的观察是绝对正确的,Unicode 人似乎更了解每个字符的使用方式。用户不记得 Unicode 数字并使用他们在键盘上看到的字符是用户的错。
    • 排版和编程语言仍然是天壤之别。也许有一天会改变,这需要一段时间。有很多 Alt+键盘快捷键可用于输入此类 Unicode 代码点,具有讽刺意味的是,它不适用于减号。
    【解决方案5】:

    使用CompareOrdinal。例如

    String.CompareOrdinal("+1","-1");
    -2
    String.CompareOrdinal("+","-");
    -2
    

    【讨论】:

      猜你喜欢
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      相关资源
      最近更新 更多