Regex.IsMatch 总是返回 false 的最常见原因是未转义特殊字符、忽略大小写或换行符影响;应使用 Regex.Escape()、指定 RegexOptions.IgnoreCase 或 RegexOptions.Singleline,并缓存 Regex 实例。

Regex.IsMatch 为什么总是返回 false?
最常见原因是没转义特殊字符,或者忽略了大小写和换行符的影响。比如想匹配 "user-name" 却直接写 Regex.IsMatch(text, "user-name"),破折号会被当正则元字符处理,实际匹配的是 "user" + 任意字符 + "name"。
- 普通字符串搜索请用
Regex.Escape()包裹关键词:Regex.IsMatch(text, Regex.Escape("user-name")) - 需要忽略大小写就加
RegexOptions.IgnoreCase参数,不加的话"User"和"user"就算不同 - 如果文本含换行,且想让
.匹配换行符,必须显式传RegexOptions.Singleline,默认不生效 - 避免在循环里反复编译正则——用
static readonly Regex字段缓存已编译的实例,否则性能掉得明显
IndexOf 和 Contains 哪个更适合简单模糊搜索?
90% 的“模糊”其实根本不需要正则。比如查日志里有没有 "timeout"、配置项是否含 "dev",用 string.IndexOf() 或 string.Contains() 更快更安全。
-
Contains()最简,但只能做子串判断,不支持通配或位置控制 -
IndexOf()能返回位置,适合后续截取或高亮;加StringComparison.OrdinalIgnoreCase可替代大部分大小写无关场景 - 别用
ToLower().Contains()做忽略大小写——生成临时字符串,GC 压力大,还可能出文化相关问题(比如土耳其语的I) - 如果只是判断存在性,
Contains()比IndexOf() != -1略快,但差别微乎其微,优先选可读性强的那个
怎么实现类似 SQL 的 LIKE 模糊逻辑(% 和 _)?
C# 没内置 LIKE 支持,但可以低成本转换:把 % 当成 .*,_ 当成 .,再用 Regex.Escape() 保护其余字符。
- 手动转义时注意顺序:先
Regex.Escape()整个字符串,再把\%替换成.*,把\_替换成. - 记得给整个正则加 ^ 和 $ 锚点,否则
"%error%"会匹配到"warning: error occurred"这种非全匹配内容 - 如果只匹配开头或结尾,比如
"abc%",生成正则时用^abc.*而不是^abc.*$,减少不必要的锚定开销 - 用户输入的 LIKE 模式要校验长度和通配符数量,防止
"%%%"展开成超长正则引发回溯爆炸
为什么 RegexOptions.Compiled 在 .NET 6+ 反而可能变慢?
.NET Core 3.0 之后 JIT 对正则做了深度优化,RegexOptions.Compiled 的优势基本消失,反而因强依赖反射和额外内存占用拖慢首次匹配。
- 除非同一正则被调用几万次以上且对首调延迟完全不敏感,否则别加
Compiled - .NET 5+ 推荐用静态工厂方法
Regex.Create()(带缓存)或直接 newRegex(pattern),运行时编译足够快 - 如果模式固定,用
static readonly Regex字段初始化一次即可,比每次 new 还省事 - 真正影响性能的是正则写法本身——嵌套量词、无界
.*、缺少原子组,这些比是否加Compiled关键得多
正则的边界容易被当成万能锤,但多数字符串查找根本用不到它。真正麻烦的从来不是怎么写对,而是忘了输入源是否可信、编码是否一致、还有那些藏在 RegexOptions 里的默认行为。










