IndexOf仅支持精确子串匹配,不适用于模糊查询;需用StartsWith/EndsWith/Contains配合StringComparison.OrdinalIgnoreCase,或Regex处理复杂模式。

IndexOf 不适合做模糊查询,它只做精确子串匹配,想实现“包含关键词”“前缀匹配”或“忽略大小写搜索”,得组合条件或换方法。
IndexOf 返回 -1 就代表没找到?不一定
它只找完全一致的子串,不处理空格、全半角、大小写、Unicode 规范化等常见差异。比如 "café".IndexOf("cafe") 返回 -1,不是因为没匹配上,而是 é(U+00E9)和 e + ´(U+0065 U+0301)在 .NET 中默认不等价。
- 用
StringComparison.OrdinalIgnoreCase显式指定比较方式,避免大小写误判:text.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) - 需要忽略 Unicode 变体时,先用
string.Normalize(NormalizationForm.FormKD)标准化再查 - 空字符串
""传给IndexOf永远返回 0,不是 bug,是规范行为,业务中要提前校验
想查“开头像”“结尾像”别硬套 IndexOf
IndexOf 本身不区分位置,靠返回值是否为 0 判断前缀、是否等于 text.Length - keyword.Length 判断后缀,既难读又易错。
- 前缀匹配直接用
text.StartsWith(keyword, StringComparison.OrdinalIgnoreCase) - 后缀匹配用
text.EndsWith(keyword, StringComparison.OrdinalIgnoreCase) - 包含匹配(最常用)用
text.Contains(keyword, StringComparison.OrdinalIgnoreCase),语义清晰,底层也做了优化 - 这些方法在 .NET 5+ 对 ASCII 字符串有 SIMD 加速,比手写
IndexOf == 0更快更安全
正则表达式才是真·模糊查询的入口
当需求变成“手机号中间四位是 *”“邮箱域名是 gmail.com”“中文姓名含‘伟’或‘芳’”,IndexOf 就彻底失效了。
- 简单模式优先用
Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase),别自己切分再循环 - 频繁调用时把
Regex实例缓存为static readonly,否则编译开销很大 - 用户输入的关键词要先用
Regex.Escape(keyword)转义,否则"a.b"会被当成正则元字符 - 注意
RegexOptions.Compiled在 .NET Core 后基本不推荐,JIT 编译已足够快,还增加启动负担
真正麻烦的不是写法,而是模糊的定义本身——用户说的“相似”到底指拼音、笔画、编辑距离,还是分词后的语义匹配。这时候 IndexOf 连起点都算不上。









