C# 中写正则要同时面对两层语法:外层是 C# 字符串,内层才是正则表达式。先确认字符串传给 Regex 的内容,再讨论匹配规则,通常更容易定位错误。
普通字符串与逐字字符串
下面两行传入的正则内容相同:
var normal = "\\d+";
var verbatim = @"\d+";
普通字符串用反斜杠转义;逐字字符串保留反斜杠,但字符串内部的一个双引号要写成两个双引号:
var quoted = @"""hello"""; // 内容是 "hello"
这里讨论的是普通和逐字字符串,不要与较新语言版本的原始字符串语法混为一谈。C# 逐字字符串说明
命名捕获与反向引用
用重复词演示捕获后再次匹配同一内容:
using System;
using System.Text.RegularExpressions;
var pattern = @"\b(?<word>\w+)\s+\k<word>\b";
var input = "what are you you talking about?";
var match = Regex.Match(
input, pattern, RegexOptions.None, TimeSpan.FromSeconds(1)
);
Console.WriteLine(match.Value); // you you
Console.WriteLine(match.Groups["word"].Value); // you
命名捕获组 word 保存第一次匹配,反向引用要求后面匹配相同内容。数字反向引用如 \1 则指向相应编号的组;替换字符串里的分组引用是另一套语法。.NET 正则反向引用
这个示例按默认大小写规则匹配,\w 和单词边界也不是完整自然语言分词器。实际处理不可信大文本时,还应限制输入规模、设置合理超时并处理超时异常。
CSS 的 url 示例只能处理受限输入
下面演示逐字字符串里的引号,以及用第一组要求闭合引号一致:
var pattern = @"url\((['""]?)([^'""()]+)\1\)";
var match = Regex.Match(
"background-image:url('image.png')",
pattern, RegexOptions.None, TimeSpan.FromSeconds(1)
);
Console.WriteLine(match.Groups[2].Value); // image.png
它只适合这里的简单形态,不支持完整 CSS 转义、嵌套结构、注释或所有空白组合。需求若是可靠理解任意样式表,应使用 CSS 解析器,而不是不断扩展一条正则。