.NET 正则引擎的特点
C# / .NET 的正则位于 System.Text.RegularExpressions 命名空间,核心是 Regex 类:默认回溯式引擎,特性上与 PCRE 接近,并有两处明显差异——后行断言允许可变长度,以及支持平衡组(balancing group)做嵌套结构配对。.NET 7 起新增 RegexOptions.NonBacktracking,用自动机实现线性时间匹配,代价是不支持环视、反向引用与原子组。
基本信息
| 适用平台 | .NET Framework / .NET Core / .NET 5+(API 基本一致) |
|---|---|
| 核心类型 | System.Text.RegularExpressions.Regex、Match、Group、Capture |
| 命名组写法 | (?<name>...) 或 (?'name'...),反向引用用 \k<name> |
| 引擎模式 | 默认回溯;非回溯模式需 NonBacktracking(.NET 7+) |
| 超时保护 | 构造 Regex 时传入 TimeSpan,或设 Regex.MatchTimeout |
| 静态方法缓存 | Regex.CacheSize 控制内部缓存条数,默认 15 |
典型使用场景
- 结构化文本解析:从日志、报文里抽取固定格式字段,配合命名组读出语义化结果
- 输入校验:整串匹配合法格式(用 IsMatch 配锚定,或 Match 后比长度)
- 批量替换:按规则重写配置或模板,配合 Regex.Replace 的分组引用与 MatchEvaluator 动态回填
- 嵌套结构提取:括号配对、标签配对这类需要计数能力的场景,用平衡组
- 高性能校验路径:把模式声明为源生成正则(GeneratedRegex)或预编译实例,避免重复编译
最小可用示例
最小可用示例
var re = new Regex(@"(?<date>[0-9]{4}-[0-9]{2}-[0-9]{2})\s+(?<level>[A-Z]+)",
RegexOptions.Compiled | RegexOptions.CultureInvariant,
TimeSpan.FromMilliseconds(200)); // 超时保护,防止回溯卡死线程
var m = re.Match("2026-10-17 ERROR disk.full");
if (m.Success) {
Console.WriteLine(m.Groups["date"].Value); // 命名组按名字取值
Console.WriteLine(m.Groups["level"].Index); // 命中位置,便于截取原文
}
string s = re.Replace("2026-10-17 ERROR", "${date}T00:00"); // 替换里用 ${name} 引用分组常用选项对照
| 选项 | 作用 | 注意事项 |
|---|---|---|
| IgnoreCase | 忽略大小写 | 默认受当前区域文化影响,建议搭配 CultureInvariant |
| Multiline | 让 ^ $ 匹配每行首尾 | 只影响锚定,不影响点的换行行为 |
| Singleline | 让点匹配换行符 | 启用后点号可跨行,抽取时要小心吞行 |
| IgnorePatternWhitespace | 允许模式内换行与注释 | 面向可读性的复杂模式必开 |
| Compiled | 编译为 IL 提升吞吐 | 短生命周期正则反而更慢,需预热与实测 |
| NonBacktracking | 线性时间引擎 | .NET 7+,不支持环视/反向引用/原子组 |
| RightToLeft | 从右向左扫描 | 取最右一处命中时有用,语义易误读 |
默认没有超时:回溯式正则在恶意或超长输入下可能长时间占住线程,在服务端表现为主线程阻塞。给所有处理外部输入的正则显式设置超时是最低成本的兜底。
IgnoreCase 默认跟随当前区域性,土耳其语环境下字母 i 的大小写规则与其他语言不同,可能出现只在特定服务器上失败的诡异 bug;不确定时应加 CultureInvariant,把匹配规则固定下来。
静态方法(Regex.IsMatch 等)走内部缓存,缓存满会淘汰并重新解析;高频路径应显式持有 Regex 实例,或用 .NET 7+ 的源生成正则,把模式在编译期转成代码,省掉运行时解析与 JIT 开销。