【问题标题】:Why does string.StartsWith("\u2D2D") always return true?为什么 string.StartsWith("\u2D2D") 总是返回 true?
【发布时间】:2019-07-06 21:52:11
【问题描述】:

我在 C# 中摆弄解析,发现对于我尝试的每个字符串,string.StartsWith("\u2D2D") 都会返回 true。这是为什么呢?

似乎它适用于每个字符。用 .Net 4.5 尝试了这段代码,调试器没有中断。

for (char i = char.MinValue; i < char.MaxValue; i++)
{
    if(!i.ToString().StartsWith("\u2d2d"))
    {
        Debugger.Break();
    }
}

【问题讨论】:

  • 这里有一行代码可以检查一堆。为我返回falseEnumerable.Range(0, 10000).Any(x =&gt; !((char)x).ToString().StartsWith("\u2D2D"))
  • 一定是因为所有的字符串都是格鲁吉亚语:D
  • 在此处查看String.StartsWith 的参考源可能会有用:referencesource.microsoft.com/#mscorlib/system/…
  • U+2D2D 是在 Unicode 版本 6.1 中添加的,似乎 6.1 的所有 4 个长度字符都有相同的问题。从一些快速测试来看,这似乎适用于所有版本 > 6.0

标签: c# string unicode startswith


【解决方案1】:

我想我会试一试的。

据我所知,U+2D2D 是在 Unicode v6.1 (source / source) 中添加的。

.NET 框架,或者更确切地说是本地调用,支持较低版本:

字符串中使用的区分区域性的排序和大小写规则 比较取决于 .NET Framework 的版本。在.NET 在Windows 8操作系统上运行的Framework 4.5,排序, 大小写、规范化和 Unicode 字符信息符合 Unicode 6.0 标准。在其他操作系统上,它符合 Unicode 5.0 标准。 (source)

因此需要将其标记为可忽略字符,其行为就好像该字符不存在一样。

字符集包括可忽略的字符,这些字符是 执行语言或文化敏感时不考虑 比较。 (source)

例子:

var culture = new CultureInfo("en-US");
int result = culture.CompareInfo.Compare("", "\u2D2D", CompareOptions.None);
Assert.AreEqual(0, result);

string.StartsWith 使用类似的实现,但改用CompareInfo.IsPrefix(string, string, CompareOptions)

【讨论】:

  • 这比其他答案 +1 更有意义。
  • 我刚刚用一个空字符串值测试了.StartsWith(),它表示为真。 IE。 "abc".StartsWith("")true。这是有道理的,因为它基本上是说底层字符串至少以 空白字符串 开头。这表明当底层的Kernel32.dll 方法FindNLSStringEx 看到它认为无效的值时,它会简单地删除它们。 (或其他一些较低级别的方法。)运行时结果为string.StartsWith("")
  • @stakx:谢谢,但我不介意。我只是想知道为什么首先会发生这种情况,也许下次我自己面对这样的事情时它会对我有所帮助。 :)
  • @EBrown:在空前缀 ("") 的情况下,FindNLSStringEx 实际上不会被调用。 .NET 端处理了 0 长度前缀的特殊情况。除此之外,根据这个答案,这是anyString.StartsWith("\u2D2D") 产生真值的逻辑原因。
  • 我刚刚用一个空白字符串值测试了 .StartsWith(),它表示 true。 这是定义的(和逻辑的)结果。如果字符串长度 == 0
猜你喜欢
  • 1970-01-01
  • 2020-01-29
  • 2012-04-03
  • 2021-09-11
  • 2015-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多