C# 正则表达式

概述

正则表达式(Regular Expression) 是一种匹配输入文本的模式。可以用来对文本进行匹配、查找、提取、替换、删除等操作。是处理字符串的强大工具

语法

基本字符

|--------|------------------------------------------------------------------------|
| \ | 将下一个字符标记为一个特殊字符 例如,"n"匹配字符"n"。"\n"匹配一个换行符。串行"\\"匹配"\"而"\("则匹配"("。 |
| . | 匹配除"\n"之外的任何单个字符 |
| * | 匹配前面的子表达式零次或多次。例如:zo*能匹配"z"以及"zoo"。*等价于{0,}。 |
| + | 匹配前面的子表达式一次或多次。例如:"zo+"能匹配"zo"以及"zoo",但不能匹配"z"。+等价于{1,}。 |
| ? | 匹配前面的子表达式零次或一次。例如:"do(es)?"可以匹配"does"或"do"。?等价于{0,1}。 |

字符类

|---------------|----------------------------------------------------------|
| xyz | 匹配所包含的任意一个字符。例如:abc可以匹配"plain"中的"a"。 |
| \^xyz | 匹配除了 中所有字符。例如:\^abc可以匹配"plain"中的"p"。 |
| a-z | 匹配指定范围内的任意字符。例如:a-z可以匹配"a"到"z"范围内的任意小写字母字符。 |
| \^a-z | 匹配任何不在指定范围内的任意字符。例如:\^a-z可以匹配任何不在"a"到"z"范围内的任意字符。 |
| x|y | 匹配x或y。例如:z|food能匹配"z"或"food"。(z|f)ood则匹配"zood"或"food"。 |

量词

|-----------|---------------------------------------------------------------------------------------|
| * | 匹配前面的子表达式零次或多次。例如:zo*能匹配"z"以及"zoo"。*等价于{0,}。 |
| + | 匹配前面的子表达式一次或多次。例如:"zo+"能匹配"zo"以及"zoo",但不能匹配"z"。+等价于{1,}。 |
| ? | 匹配前面的子表达式零次或一次。例如:"do(es)?"可以匹配"does"或"do"。?等价于{0,1}。 |
| {n} | 匹配前面的模式恰好 n 次。例如,o{2}不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。 |
| {n,} | 匹配前面的模式至少 n 次。例如,o{2,}不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。o{1,}等价于o+。o{0,}则等价于o*。 |
| {n,m} | 匹配前面的模式至少 n 次且不超过 m 次。例如,o{1,3}将匹配"fooooood"中的前三个o。"o{0,1}"等价于"o?"。请注意在逗号和两个数之间不能有空格。 |

边界符号

|---------|-------------------------------------------------------|
| ^ | 匹配输入字符串的开始位置。 |
| $ | 匹配输入字符串的结束位置。 |
| \b | 匹配一个单词边界。例如,er\b可以匹配"never"中的"er",但不能匹配"verb"中的"er"。 |
| \B | 匹配非单词边界。er\b能匹配"verb"中的"er",但不能匹配"never"中的"er"。 |

特殊字符

|---------|--------------------------------------------------|
| \d | 匹配一个数字字符。等价于0-9。 |
| \D | 匹配一个非数字字符。等价于\^0-9。 |
| \w | 匹配包括下划线的任何单词字符(字母、数字、下划线)。等价于A-Za-z0-9_。 |
| \W | 匹配任何非单词字符。等价于\^A-Za-z0-9_ |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 \\f\\n\\r\\t\\v。 |
| \S | 匹配任何非空白字符。等价于\^ \\f\\n\\r\\t\\v。 |
| \f | 匹配一个换页符。等价于\x0c和\cL。 |
| \n | 匹配一个换行符。等价于\x0a和\cJ。 |
| \r | 匹配一个回车符。等价于\x0d和\cM。 |

Regex

C#通过System.Text.RegularExpressions命名空间提供了完整的正则表达式支持。

Regex类核心方法

1. IsMatch - 判断是否匹配

cs 复制代码
bool isMatch = Regex.IsMatch("abc123", @"\d+"); // true (包含数字)

2. Match - 获取第一个匹配

cs 复制代码
Match match = Regex.Match("abc123def456", @"\d+");
Console.WriteLine(match.Value); // "123"
Console.WriteLine(match.Index); // 3 (匹配开始位置)

3. Matches - 获取所有匹配

cs 复制代码
MatchCollection matches = Regex.Matches("abc123def456", @"\d+");
foreach (Match m in matches)
{
    Console.WriteLine(m.Value); // 输出"123"和"456"
}

4. Replace - 替换匹配内容

cs 复制代码
string result = Regex.Replace("abc123def456", @"\d+", "###");
// 结果: "abc###def###"

5. Split - 根据模式分割字符串

cs 复制代码
string[] parts = Regex.Split("one,two,,three", @",");
// 结果: ["one", "two", "", "three"]

RegexOptions选项

cs 复制代码
// 常用选项组合使用
Regex regex = new Regex(pattern, 
    RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);

|-----------------------------|-----------------|
| 选项 | 描述 |
| IgnoreCase | 忽略大小写 |
| Multiline | 多行模式(^$匹配每行首尾) |
| Compiled | 编译正则表达式(提高性能) |
| Singleline | 单行模式(.匹配包括\n) |
| ExplicitCapture | 只捕获命名分组 |
| IgnorePatternWhitespace | 忽略模式中的空白 |

模板参考

数字校验

|---------------|----------------------------------------------------------|
| 描述 | 模板 |
| 全数字 | @"^0-9*"** | | **n位的数字** | **@"\^\\d{n}" |
| 至少n位的数字 | @"^\d{n,}"** | | **m-n位的数字** | **@"\^\\d{m,n}" |
| 正数、负数、和小数 | @"^(\-|\+)?\d+(\.\d+)?** | | **非零的正整数** | **@"\^\[1-9\]\\d\*" |
| 非零的负整数 | @"^-1-9\d*"** | | **非负整数** | **@"\^\\d+" |
| 非正整数 | @"^-1-9\d*|0"** | | **正浮点数** | **@"\^\[1-9\]\\d\*\\.\\d\*\|0\\.\\d\*\[1-9\]\\d\*" |
| 负浮点数 | @"^-(1-9\d*\.\d*|0\.\d*1-9\d*)"** | | **非负浮点数** | **@"\^\\d+(\\.\\d+)?" |
| 非正浮点数 | @"^((-\d+(\.\d+)?)|(0+(\.0+)?))"** | | **浮点数** | **@"\^(-?\\d+)(\\.\\d+)?" |

字符校验

|----------------------------|------------------------------------------|
| 描述 | 模板 |
| 汉字 | @"^\\u4e00-\\u9fa5{0,}"** | | **英文和数字** | **@"\^\[A-Za-z0-9\]+" |
| 长度为3-20的所有字符 | @"^.{3,20}"** | | **由26个英文字母组成的字符串** | **@"\^\[A-Za-z\]+" |
| 由26个大写英文字母组成的字符串 | @"^A-Z+"** | | **由26个小写英文字母组成的字符串** | **@"\^\[a-z\]+" |
| 由数字和26个英文字母组成的字符串 | @"^A-Za-z0-9+"** | | **由数字、26个英文字母或者下划线组成的字符串** | **@"\^\\w+" |
| 中文、英文、数字包括下划线 | @"^\\u4E00-\\u9FA5A-Za-z0-9_+"** | | **中文、英文、数字但不包括下划线等符号** | **@"\^\[\\u4E00-\\u9FA5A-Za-z0-9\]+" |
| 禁止输入含有~的字符 | @"\^\~\\x22+" |

特定校验

cs 复制代码
//Email地址
Regex reg = new Regex(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
//域名
Regex reg = new Regex(@"[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?");
//InternetURL
Regex reg = new Regex(@"[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$");
//手机号码
Regex reg = new Regex(@"^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$");
//电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX)
Regex reg = new Regex(@"^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$");
//国内电话号码(0511-4405222、021-87888822)
Regex reg = new Regex(@"\d{3}-\d{8}|\d{4}-\d{7}");
//身份证号(15位、18位数字)
Regex reg = new Regex(@"^\d{15}|\d{18}$");
//短身份证号码(数字、字母x结尾)
Regex reg = new Regex(@"^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$");
//帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)
Regex reg = new Regex(@"^[a-zA-Z][a-zA-Z0-9_]{4,15}$");
//密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
Regex reg = new Regex(@"^[a-zA-Z]\w{5,17}$");
//强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)
Regex reg = new Regex(@"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$");
//日期格式
Regex reg = new Regex(@"^\d{4}-\d{1,2}-\d{1,2}");
//一年的12个月(01~09和1~12)
Regex reg = new Regex(@"^(0?[1-9]|1[0-2])$");
//一个月的31天(01~09和1~31)
Regex reg = new Regex(@"^((0?[1-9])|((1|2)[0-9])|30|31)$");
//钱的输入格式:
//有四种钱的表示形式我们可以接受:"10000.00″ 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000"
Regex reg = new Regex(@"^[1-9][0-9]*$");
//这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0″不通过,所以我们采用下面的形式
Regex reg = new Regex(@"^(0|[1-9][0-9]*)$");
//一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号
Regex reg = new Regex(@"^(0|-?[1-9][0-9]*)$");
//这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分
Regex reg = new Regex(@"^[0-9]+(.[0-9]+)?$");
//必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的
Regex reg = new Regex(@"^[0-9]+(.[0-9]{2})?$");
//这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样
Regex reg = new Regex(@"^[0-9]+(.[0-9]{1,2})?$");
//这样就允许用户只写一位小数。下面我们该考虑数字中的逗号了,我们可以这样
Regex reg = new Regex(@"^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$");
//1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须
Regex reg = new Regex(@"^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$");
//备注:这就是最终结果了,别忘了"+"可以用"*"替代。如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
//xml文件
Regex reg = new Regex(@"^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$");
//中文字符的正则表达式
Regex reg = new Regex(@"[\u4e00-\u9fa5]");
//双字节字符
Regex reg = new Regex(@"[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))");
//空白行的正则表达式,可用来删除空白行
Regex reg = new Regex(@"\n\s*\r");
//HTML标记的正则表达式
Regex reg = new Regex(@"<(\S*?)[^>]*>.*?</\1>|<.*? />");// (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
//首尾空白字符的正则表达式
Regex reg = new Regex(@"^\s*|\s*$或(^\s*)|(\s*$)");// (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
//腾讯QQ号
Regex reg = new Regex(@"[1-9][0-9]{4,}"); //(腾讯QQ号从10000开始)
//中国邮政编码
Regex reg = new Regex(@"[1-9]\d{5}(?!\d)");// (中国邮政编码为6位数字)
//IP地址
Regex reg = new Regex(@"\d+\.\d+\.\d+\.\d+");// (提取IP地址时有用)
//IP地址
Regex reg = new Regex(@"((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))");

适用场景和优缺点

优缺点

优点

  1. 强大的模式匹配能力
  • 复杂模式处理:能轻松处理复杂的字符串模式,如电子邮件、URL、电话号码等验证

  • 单行解决复杂问题:一个简洁的正则表达式可能替代多行传统字符串操作代码

  1. 代码简洁高效
  • 减少代码量:相比手动编写字符串处理逻辑,正则表达式通常更简洁

  • 内置优化:.NET的Regex引擎经过高度优化,对常见模式有良好性能

缺点

1、可读性差,难以理解

2、团队协作障碍:不是所有开发者都精通正则表达式

适合使用正则表达式的情况

  1. 验证复杂但标准化的输入格式(如电子邮件、URL、电话号码)

  2. 从结构化文本中提取特定数据

  3. 需要跨多平台/语言保持一致的文本处理逻辑

  4. 处理基于模式的批量文本替换

不适合使用正则表达式的情况

  1. 简单的字符串操作(如ContainsStartsWith等能解决的)

  2. 解析复杂的分层结构(如XML/JSON - 应使用专用解析器)

  3. 性能关键的场景且模式复杂时

  4. 业务规则频繁变化的需求

正则表达式是C#开发者的强大工具,但应当谨慎使用,权衡其优缺点,在适当的场景下发挥它的最大价值。

相关推荐
吴声子夜歌21 小时前
正则指引——Ruby
开发语言·正则表达式·ruby
吴声子夜歌1 天前
正则指引——Golang
开发语言·golang·正则表达式
吴声子夜歌2 天前
正则指引——PHP
开发语言·正则表达式·php
吴声子夜歌4 天前
正则指引——断言
正则表达式
吴声子夜歌4 天前
正则指引——匹配原理
java·正则表达式
吴声子夜歌5 天前
正则表达式——环视
开发语言·正则表达式
吴声子夜歌6 天前
正则表达式——边界
正则表达式
营养充电站6 天前
C++23 新特性在 CLion 中的实战体验
macos·docker·jupyter·正则表达式
吴声子夜歌7 天前
正则表达式——字符组
正则表达式