C#String.IndexOf - 具有特殊字符的文本给出错误的结果

时间:2018-02-04 23:41:35

标签: c# special-characters indexof

"* {{IPA|ɪntɹəvaɪtl}}̩".IndexOf("}}")返回-1。

"* {{IPA|ɪntɹəvaɪtl}}".IndexOf("}}")返回18.

我希望第一个样本返回18。

请注意第一个样本中的结尾双括号后面有一个特殊字符U + 0329。

将垂直线组合在U + 0329以下

有人可以告诉我为什么它会返回-1而不是18吗?即使在序数搜索中,字符串包含“}}”,因此它不应返回-1。

1 个答案:

答案 0 :(得分:2)

(注意:我不是Unicode大师。)

问题可能是字符U + 0329是组合字符。如果您使用字母字符替换字符串中的}},您会更清楚地看到问题:

"the̩"

请注意,在这种情况下,U + 0329在字符串中的e上显示为修饰符,从而改变了角色的视觉表示。使用}}字符对也会发生同样的情况,尽管很奇怪。

你所拥有的不是一对 RIGHT CURLY BRACKET 字符,它是一个 RIGHT CURLY BRACKET 和一个 RIGHT CURLY BRACKET +组合垂直线 em> 字形。当您使用默认的StringComparison选项进行比较时,搜索字符串中的第二个 RIGHT CURLY BRACKET 不匹配,因为它与不同的字形(字符序列)匹配

然而,使用StringComparison.Ordinal会改变处理Unicode的方式,忽略U + 0329的 COMBINING 属性并简单地比较代码点。

这有趣的地方在于您搜索重音字符时,因为在使用CurrentCulture或{{1}时,通常会有多个字形看起来相同且比较相同但是组成不同。

LATIN SMALL LETTER E with ACUTE InvariantCulture”代码点U + 00E9与字形 LATIN SMALL LETTER E + COMBINING ACUTE ACCENT (U + 0065,U + 0301)“é”。它们看起来相同并且在您使用时进行比较,但在使用InvariantCulture比较时则不一样。

你可以做很多工作,只是试图定义处理这个问题的“正确”方法,更不用说实现这种方式了。我经常发现最好只是接受一些字符序列会给你带来麻烦并选择一个Ordinal值。