c#正则表达式
在 C# 中,正则表达式是处理文本模式匹配和字符串操作的强大工具,通过System.Text.RegularExpressions
命名空间提供支持。以下是关于 C# 正则表达式的详细介绍:
1. 基本概念
正则表达式是用于定义字符串模式的字符序列,可用于:
-
验证输入格式(如邮箱、手机号)
-
提取特定内容(如 URL、日期)
-
替换或分割字符串
核心类:
-
Regex
:表示编译后的正则表达式。 -
Match
:表示单个匹配结果。 -
MatchCollection
:表示多个匹配结果的集合。 -
Group
:表示捕获组(括号内的子表达式)。
2. 常用元字符和语法
.
a.b
匹配 acb
^
^Hello
匹配以Hello
开头的字符串$
world$
匹配以world
结尾的字符串*
ab*
匹配 a
、ab
、abb
等+
ab+
匹配 ab
、abb
,但不匹配 a
?
ab?
匹配 a
或 ab
{n}
a{3}
匹配 aaa
{n,}
a{2,}
匹配 aa
、aaa
等{n,m}
a{2,3}
匹配 aa
或 aaa
[]
[abc]
匹配 a
、b
或 c
[^]
[^abc]
匹配除 a
、b
、c
外的字符|
a|b
匹配 a
或 b
()
(ab)+
匹配 ab
、abab
等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]$
^https?://[^\\s/$.?#].[^\\s]*$
^-?\\d+(\\.\\d+)?$
^[\\u4e00-\\u9fa5]+$
8. 性能优化建议
-
重复使用同一正则表达式:编译开销较大,建议创建静态实例:
private static readonly Regex EmailRegex = new Regex(@\"[a-z]+@[a-z]+\\.[a-z]+\");
-
避免回溯陷阱:复杂嵌套量词(如
(a+)*
)可能导致指数级性能下降。 -
使用非捕获组:不需要提取内容时,用
(?:pattern)
代替(pattern)
减少内存开销。
掌握这些例子和方法后,你可以处理大多数文本处理场景。如需更复杂的模式,可以组合使用不同的元字符和选项。