.NET 7中IndexOf与Contains处理非间距字符的异常问题
问题根源与解决方案
核心原因
这个问题的关键在于**.NET中Contains和IndexOf的默认字符串比较规则不同**:
string.Contains(string)默认使用序数比较(Ordinal):逐字符精确匹配,不考虑文化差异或Unicode组合字符的等价性。因此"Foo" + (char)1618中,"Foo"作为前缀子串能被精确识别,返回true。string.IndexOf(string)默认使用当前文化比较(CurrentCulture):会遵循当前系统文化的排序规则,你用到的(char)1618是U+0652(阿拉伯语下标Alef),属于非间距组合字符——它会和前面的基字符("Foo"的最后一个字符'o')被视为一个排序单元,导致查找"Foo"时无法匹配到结尾的"o",返回-1。
当你在"Foo"和组合字符之间添加空格后,两者被分隔开,当前文化比较不再将它们视为整体,因此IndexOf能正常匹配到"Foo",返回0。
解决方案
要让两个方法行为一致,有两种可选方式:
- 显式指定序数比较:给
IndexOf传入StringComparison.Ordinal参数,和Contains的默认行为对齐:("Foo" + (char)1618).IndexOf("Foo", StringComparison.Ordinal); // 返回0 - Unicode规范化后查找:如果需要考虑Unicode字符的等价性(比如组合字符与预合成字符的匹配),可以先将字符串规范化为NFC或NFD格式:
var str = ("Foo" + (char)1618).Normalize(NormalizationForm.FormC); str.IndexOf("Foo"); // 返回0
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

