> 技术文档 > c#正则表达式

c#正则表达式

在 C# 中,正则表达式是处理文本模式匹配和字符串操作的强大工具,通过System.Text.RegularExpressions命名空间提供支持。以下是关于 C# 正则表达式的详细介绍:

1. 基本概念

正则表达式是用于定义字符串模式的字符序列,可用于:

  • 验证输入格式(如邮箱、手机号)

  • 提取特定内容(如 URL、日期)

  • 替换或分割字符串

核心类

  • Regex:表示编译后的正则表达式。

  • Match:表示单个匹配结果。

  • MatchCollection:表示多个匹配结果的集合。

  • Group:表示捕获组(括号内的子表达式)。

2. 常用元字符和语法

元字符 含义 示例 . 匹配任意单个字符(除换行符) a.b 匹配 acb ^ 匹配字符串开头 ^Hello 匹配以Hello开头的字符串 $ 匹配字符串结尾 world$ 匹配以world结尾的字符串 * 匹配前面的元素 0 次或多次 ab* 匹配 aababb+ 匹配前面的元素 1 次或多次 ab+ 匹配 ababb,但不匹配 a ? 匹配前面的元素 0 次或 1 次 ab? 匹配 aab {n} 匹配前面的元素恰好 n 次 a{3} 匹配 aaa {n,} 匹配前面的元素至少 n 次 a{2,} 匹配 aaaaa{n,m} 匹配前面的元素 n 到 m 次 a{2,3} 匹配 aaaaa [] 匹配方括号内的任意一个字符 [abc] 匹配 abc [^] 匹配不在方括号内的任意字符 [^abc] 匹配除 abc 外的字符 | 或运算,匹配左侧或右侧的模式 a|b 匹配 ab () 分组,用于捕获子表达式或优先级 (ab)+ 匹配 ababab

3. 预定义字符类

字符类 等价于 含义 \\d [0-9] 匹配数字 \\D [^0-9] 匹配非数字 \\w [a-zA-Z0-9_] 匹配字母、数字或下划线 \\W [^a-zA-Z0-9_] 匹配非字母、数字或下划线 \\s [ \\t\\n\\r\\f\\v] 匹配空白字符(空格、制表符等) \\S [^ \\t\\n\\r\\f\\v] 匹配非空白字符

4. 量词的贪婪与非贪婪模式

  • 贪婪模式(默认):尽可能多地匹配。

    \"aabab\".Match(\"a.*b\")  // 匹配 \"aabab\"(最长匹配)
  • 非贪婪模式(? 后加):尽可能少地匹配。

    \"aabab\".Match(\"a.*?b\") // 匹配 \"aab\"(最短匹配)

5. C# 中的正则表达式用法

5.1 创建正则表达式
using System.Text.RegularExpressions;​// 方式1:直接创建实例Regex regex = new Regex(@\"pattern\");​// 方式2:静态方法(自动缓存)Match match = Regex.Match(input, @\"pattern\");
5.2 常用方法
方法 描述 IsMatch(input) 检查输入是否匹配模式 Match(input) 返回第一个匹配结果 Matches(input) 返回所有匹配结果的集合 Replace(input, replacement) 替换匹配的文本 Split(input) 根据匹配结果分割字符串

6. 示例代码

6.1 验证邮箱格式
string email = \"test@example.com\";bool isValid = Regex.IsMatch(email, @\"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$\");// 输出:True
6.2 提取 URL 中的域名
string url = \"https://www.example.com/path\";Match match = Regex.Match(url, @\"https?://([^/]+)\");if (match.Success) {    string domain = match.Groups[1].Value; // 输出:www.example.com}
6.3 替换文本中的数字
string input = \"Hello 123 World 456\";string result = Regex.Replace(input, @\"\\d+\", \"NUMBER\");// 输出:Hello NUMBER World NUMBER
6.4 分割字符串
string input = \"Hello,World;Foo Bar\";string[] parts = Regex.Split(input, @\"[,\\s;]+\");// 输出:[\"Hello\", \"World\", \"Foo\", \"Bar\"]

7. 性能优化

  • 静态方法:对于频繁使用的正则表达式,优先使用静态方法(如Regex.Match),因为它们会自动缓存编译后的表达式。

  • 编译选项:使用

    RegexOptions.Compiled

    可将表达式编译为程序集,提高性能(适用于多次使用的复杂模式)。

    Regex regex = new Regex(@\"pattern\", RegexOptions.Compiled);
  • 懒惰求值:使用Matches方法时,结果是延迟计算的,避免一次性加载所有匹配项。

8. 注意事项

  • 转义字符:在正则表达式中使用反斜杠\\时,需要在 C# 字符串中写为\\,或使用逐字字符串@\"...\"

    @\"\\\\d\"  // 等价于 \"\\\\\\\\d\",匹配反斜杠后接数字
  • 回溯陷阱:复杂的正则表达式可能导致性能问题,例如嵌套量词(如(a+)*)会引发指数级回溯。

9. 常用正则表达式模式

  • 手机号^1[3-9]\\d{9}$

  • IPv4 地址^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

  • HTML 标签]+>

  • 日期(YYYY-MM-DD)^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$

通过掌握这些基础知识,你可以在 C# 中灵活运用正则表达式处理各种文本操作。如果需要更复杂的模式或性能优化,可以进一步研究RegexOptions和捕获组的高级用法。

具体例子:

以下是 C# 正则表达式的具体例子和使用方法,涵盖常见场景和 API 用法:

1. 验证类示例

1.1 验证手机号
string phone = \"13800138000\";bool isValid = Regex.IsMatch(phone, @\"^1[3-9]\\d{9}$\");// 输出:True
1.2 验证密码强度(至少 8 位,包含大小写字母和数字)
string password = \"Passw0rd\";bool isStrong = Regex.IsMatch(password, @\"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,}$\");// 输出:True

2. 提取类示例

2.1 从 HTML 中提取所有 URL
string html = \"Link \";MatchCollection matches = Regex.Matches(html, @\"https?://\\S+\");foreach (Match match in matches) {    Console.WriteLine(match.Value); // 输出:https://example.com}
2.2 提取日期中的年、月、日
string date = \"2023-10-01\";Match match = Regex.Match(date, @\"(\\d{4})-(\\d{2})-(\\d{2})\");if (match.Success) {    string year = match.Groups[1].Value; // 2023    string month = match.Groups[2].Value; // 10    string day = match.Groups[3].Value; // 01}

3. 替换类示例

3.1 敏感信息脱敏(手机号中间 4 位替换为星号)
string phone = \"13800138000\";string masked = Regex.Replace(phone, @\"(\\d{3})\\d{4}(\\d{4})\", \"$1****$2\");// 输出:138****8000
3.2 替换 HTML 标签为纯文本
string html = \"

Hello World!

\";string text = Regex.Replace(html, @\"]*>\", \"\");// 输出:Hello World!

4. 分割类示例

4.1 按逗号或空格分割字符串
string input = \"Apple, Banana Orange;Grape\";string[] fruits = Regex.Split(input, @\"[,\\s;]+\");// 输出:[\"Apple\", \"Banana\", \"Orange\", \"Grape\"]

5. 高级用法

5.1 忽略大小写匹配
string text = \"Hello World\";bool isMatch = Regex.IsMatch(text, @\"world\", RegexOptions.IgnoreCase);// 输出:True
5.2 多行模式匹配
string text = \"Line 1\\nLine 2\\nLine 3\";MatchCollection matches = Regex.Matches(text, @\"^Line \\d\", RegexOptions.Multiline);// 匹配所有以\"Line\"开头的行
5.3 正向预查(查找后面跟特定内容的文本)
string text = \"apple$10, banana$20\";MatchCollection matches = Regex.Matches(text, @\"\\w+(?=\\$\\d+)\");// 输出:[\"apple\", \"banana\"]

6. 完整代码示例

以下是一个完整的程序,演示如何使用正则表达式提取网页中的邮箱地址:

using System;using System.Text.RegularExpressions;​class Program {    static void Main() {        string html = @\"            

Contact us at support@example.com or info@company.net

           Admin        \";​        // 定义邮箱正则表达式        string pattern = @\"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+\";                // 执行匹配        MatchCollection matches = Regex.Matches(html, pattern);                // 输出结果        Console.WriteLine(\"找到的邮箱地址:\");        foreach (Match match in matches) {            Console.WriteLine(match.Value);       }   }}​/* 输出:找到的邮箱地址:support@example.cominfo@company.netadmin@domain.com*/

7. 常用正则表达式模式

场景 正则表达式模式 说明 邮箱验证 ^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$ 简单邮箱格式验证 身份证号验证 ^\\d{17}[\\dXx]$ 18 位身份证号(含 X 结尾) URL 验证 ^https?://[^\\s/$.?#].[^\\s]*$ 验证 HTTP/HTTPS URL 数字验证 ^-?\\d+(\\.\\d+)?$ 整数或小数 汉字验证 ^[\\u4e00-\\u9fa5]+$ 纯中文字符

8. 性能优化建议

  • 重复使用同一正则表达式:编译开销较大,建议创建静态实例:

    private static readonly Regex EmailRegex = new Regex(@\"[a-z]+@[a-z]+\\.[a-z]+\");
  • 避免回溯陷阱:复杂嵌套量词(如(a+)*)可能导致指数级性能下降。

  • 使用非捕获组:不需要提取内容时,用(?:pattern)代替(pattern)减少内存开销。

掌握这些例子和方法后,你可以处理大多数文本处理场景。如需更复杂的模式,可以组合使用不同的元字符和选项。