C# String.IndexOf - 带有特殊字符的文本返回错误结果
C# String.IndexOf - Text with special character returning wrong result
"* {{IPA|ɪntɹəvaɪtl}}̩".IndexOf("}}")
returns -1.
"* {{IPA|ɪntɹəvaɪtl}}".IndexOf("}}")
returns 18.
我希望第一个样本 return 18.
请注意第一个示例中结尾的双括号后面有一个特殊字符 U+0329。
结合U+0329下方的竖线
为什么 returning -1 而不是 18?即使在顺序搜索中,字符串包含“}}”,所以它不应该 return -1.
(注意:我不是 Unicode 大师。)
问题可能在于字符 U+0329 是组合字符。如果将字符串中的 }}
替换为字母字符,您会更清楚地看到问题:
"the̩"
请注意,在这种情况下,U+0329 作为修饰符出现在字符串中的 e
上,改变了字符的视觉表示。 }}
字符对也发生了同样的情况,尽管很奇怪。
你得到的不是一对 RIGHT CURLY BRACKET 个字符,而是一个 RIGHT CURLY BRACKET 和一个 右花括号 + 组合下方垂直线 字形 。当您使用默认 StringComparison
选项进行比较时,搜索字符串中的第二个 RIGHT CURLY BRACKET 不匹配,因为它正在与字形(字符序列)匹配那是不同的。
然而,使用 StringComparison.Ordinal
会改变处理 Unicode 的方式,忽略 U+0329 的 COMBINING 属性并简单地比较代码点。
当您搜索重音字符时,这变得有趣,因为通常有多个看起来相同的字形,并且 比较 使用 CurrentCulture
时相同或 InvariantCulture
但组成不同。
例如,带尖音符号的拉丁文小写字母 E“é
”代码点 U+00E9 与字形 拉丁文小写字母 E 的比较+ 组合重音 (U+0065, U+0301) “é
”。当您使用 InvariantCulture
时,它们看起来相同且比较相同,但当您使用 Ordinal
比较时则不同。
你可以做很多工作只是试图定义什么是 'right' 处理这个的方法,更不用说实现那个方法了。我经常发现最好接受某些字符序列会给您带来麻烦并选择一个 StringComparison
值。
"* {{IPA|ɪntɹəvaɪtl}}̩".IndexOf("}}")
returns -1.
"* {{IPA|ɪntɹəvaɪtl}}".IndexOf("}}")
returns 18.
我希望第一个样本 return 18.
请注意第一个示例中结尾的双括号后面有一个特殊字符 U+0329。
结合U+0329下方的竖线
为什么 returning -1 而不是 18?即使在顺序搜索中,字符串包含“}}”,所以它不应该 return -1.
(注意:我不是 Unicode 大师。)
问题可能在于字符 U+0329 是组合字符。如果将字符串中的 }}
替换为字母字符,您会更清楚地看到问题:
"the̩"
请注意,在这种情况下,U+0329 作为修饰符出现在字符串中的 e
上,改变了字符的视觉表示。 }}
字符对也发生了同样的情况,尽管很奇怪。
你得到的不是一对 RIGHT CURLY BRACKET 个字符,而是一个 RIGHT CURLY BRACKET 和一个 右花括号 + 组合下方垂直线 字形 。当您使用默认 StringComparison
选项进行比较时,搜索字符串中的第二个 RIGHT CURLY BRACKET 不匹配,因为它正在与字形(字符序列)匹配那是不同的。
然而,使用 StringComparison.Ordinal
会改变处理 Unicode 的方式,忽略 U+0329 的 COMBINING 属性并简单地比较代码点。
当您搜索重音字符时,这变得有趣,因为通常有多个看起来相同的字形,并且 比较 使用 CurrentCulture
时相同或 InvariantCulture
但组成不同。
例如,带尖音符号的拉丁文小写字母 E“é
”代码点 U+00E9 与字形 拉丁文小写字母 E 的比较+ 组合重音 (U+0065, U+0301) “é
”。当您使用 InvariantCulture
时,它们看起来相同且比较相同,但当您使用 Ordinal
比较时则不同。
你可以做很多工作只是试图定义什么是 'right' 处理这个的方法,更不用说实现那个方法了。我经常发现最好接受某些字符序列会给您带来麻烦并选择一个 StringComparison
值。