普通视图
C# 正则表达式(2):Regex 基础语法与常用 API 全解析
一、IsMatch 入门
using System;
using System.Text.RegularExpressions;
class Program
{
static void Main()
{
string input = "2025-12-18";
string pattern = @"^\d{4}-\d{2}-\d{2}$";
bool isValid = Regex.IsMatch(input, pattern);
Console.WriteLine(isValid); // True
}
}
解析::
-
pattern是正则表达式,@"..."是 C# 的逐字字符串字面量。 -
^和$:锚点,表示“从头到尾整串匹配” -
\d{4}:4 位数字。 -
-:字面量“-”。 -
Regex.IsMatch:看字符串中是不是“满足这个模式”。
二、C# Regex 的 5 个核心方法
在 System.Text.RegularExpressions.Regex 里,最常用的就是这 5 个方法:
IsMatchMatchMatchesReplaceSplit
三、Regex.IsMatch:最常用的“判断是否匹配”
IsMatch 是表单校验、输入合法性检查中使用频率最高的方法。
bool isEmail = Regex.IsMatch(email, pattern);
示例:
string input = "Order12345";
string pattern = @"\d{3}";
bool has3Digits = Regex.IsMatch(input, pattern); // True
注意点:
- 默认只要“包含”满足 pattern 的子串,就返回 true,并不要求整个字符串都完全匹配。
- 如果你想“整个字符串必须符合这个规则”,要在 pattern 外面加上
^和$:
// 只允许由 3~5 位数字组成,不允许多一个字符
string pattern = @"^\d{3,5}$";
四、Regex.Match:获取第一个匹配
string text = "My phone is 123-456-7890.";
string pattern = @"\d{3}-\d{3}-\d{4}";
Match match = Regex.Match(text, pattern);
if (match.Success)
{
Console.WriteLine(match.Value); // "123-456-7890"
Console.WriteLine(match.Index); // 起始索引
Console.WriteLine(match.Length); // 匹配的长度
}
常用成员:
-
match.Success:是否匹配成功。 -
match.Value:匹配到的字符串。 -
match.Index:匹配在原文本中的起始位置(从 0 开始)。 -
match.Length:长度。
Regex.Match 也有带起始位置、带 RegexOptions 的重载:
五、Regex.Matches:获取所有匹配结果(多个)
string text = "ID: 100, 200, 300";
string pattern = @"\d+";
MatchCollection matches = Regex.Matches(text, pattern);
foreach (Match m in matches)
{
Console.WriteLine($"{m.Value} at {m.Index}");
}
// 输出:
// 100 at 4
// 200 at 9
// 300 at 14
解析:
- 返回的是一个
MatchCollection,可以foreach遍历。 - 每个
Match和前面一样,有Value、Index、Groups等属性。
六、Regex.Replace:按模式搜索并替换
Regex.Replace 和字符串的 Replace 很像,但支持模式匹配。
1. 固定字符串替换匹配内容
string input = "2025/12/18";
string pattern = @"/";
string result = Regex.Replace(input, pattern, "-");
Console.WriteLine(result); // "2025-12-18"
这相当于“把所有 / 都换成 -”,和 input.Replace("/", "-") 类似,但 pattern 可以写得更复杂。
2.用捕获组重排内容
string input = "2025-12-18";
string pattern = @"(\d{4})-(\d{2})-(\d{2})";
// 把 yyyy-MM-dd 改成 dd/MM/yyyy
string result = Regex.Replace(input, pattern, "$3/$2/$1");
// result: "18/12/2025"
解析:
这里的 $1、$2、$3 是捕获组
3. 更高级的 MatchEvaluator 版本
string input = "Price: 100 USD, 200 USD";
string pattern = @"(\d+)\s*USD";
string result = Regex.Replace(input, pattern, m =>
{
int value = int.Parse(m.Groups[1].Value);
int converted = (int)(value * 7.2); // 假设汇率
return $"{converted} CNY";
});
Console.WriteLine(result);
// "Price: 720 CNY, 1440 CNY"
七、Regex.Split:按“模式”切割字符串
可以实现多分隔符的切割
string input = "apple, banana; cherry|date";
string pattern = @"[,;|]\s*"; // 逗号;分号;竖线 + 可选空白
string[] parts = Regex.Split(input, pattern);
foreach (var p in parts)
{
Console.WriteLine(p);
}
// apple
// banana
// cherry
// date
八、正则基础语法(一):字面字符与转义
1. 字面字符
绝大多数普通字符在正则里就是字面意思:
- 模式:
abc→ 匹配文本中出现的abc。 - 模式:
hello→ 匹配文本中出现的hello。
2. 特殊字符(元字符)
这些字符在正则中有特殊含义:
-
.^$*+?()[]{}\|
如果你要匹配其中任意一个“字面意义上的”字符,就要用 \ 转义。
例如:
- 匹配一个点号
.→ 模式\. - 匹配一个星号
*→ 模式\* - 匹配一对括号
(abc)→ 模式\(+abc+\)
在 C# 中配合逐字字符串:
string pattern = @"\."; // 匹配 "."
string pattern2 = @"\*"; // 匹配 "*"
如果不用 @:
string pattern = "\\."; // C# 字符串里写成 "\\." 才表示一个反斜杠+点
实践中几乎所有正则字符串都用 @"",可以少一半反斜杠。
九、正则基础语法(二):预定义字符类 \d / \w / \s
预定义字符类是正则里最常用的工具,它们代表一类字符。
1. \d / \D:数字与非数字
-
\d:digit,匹配 0–9 的任意一位数字,相当于[0-9]。 -
\D:非数字,相当于[^0-9]。
示例:匹配一个或多个数字
string pattern = @"\d+";
2. \w / \W:单词字符与非单词字符
-
\w:word,匹配字母、数字和下划线,相当于[A-Za-z0-9_]。 -
\W:非\w。
示例:匹配“单词”(一串字母数字下划线)
string pattern = @"\w+";
3. \s / \S:空白字符与非空白字符
-
\s:space,匹配空格、制表符、换行等所有空白字符。 -
\S:非空白。
示例:
string pattern = @"\s+"; // 匹配一个或多个空白
结语
点个赞,关注我获取更多实用 C# 技术干货!如果觉得有用,记得收藏本文
C# 正则表达式:量词与锚点——从“.*”到精确匹配
一、量词:告诉引擎“要重复多少次”
量词出现在一个“单元”后面,表示这个单元要重复多少次。
单元可以是:
- 一个普通字符:
a - 一个字符类:
\d、[A-Z] - 一个分组:
(ab)
1. 常见量词一览
-
?:0 或 1 次 -
*:0 次或多次 -
+:1 次或多次 -
{n}:恰好 n 次 -
{n,}:至少 n 次 -
{n,m}:n 到 m 次之间
示例:
using System.Text.RegularExpressions;
string pattern = @"^\d{3,5}$";
bool ok = Regex.IsMatch("1234", pattern); // True
2. 量词是作用在“前一项”上的
注意:ab+ 只会把 + 作用到 b 上:
- 模式:
ab+- 匹配:"ab"、"abb"、"abbbb"...
- 模式:
(ab)+- 匹配:"ab"、"abab"、"ababab"...
也就是说,当你想对一“串”东西使用量词,一定要用括号分组。
二、贪婪 vs 懒惰:* 和 *? 的根本区别
量词在默认情况下是“贪婪”的:
- 在不影响匹配成功的前提下,尽可能多地吃字符。
1. 贪婪匹配:.*
string input = "<tag>content</tag><tag>more</tag>";
string pattern = @"<tag>.*</tag>";
Match m = Regex.Match(input, pattern);
Console.WriteLine(m.Value);
匹配结果:
<tag>content</tag><tag>more</tag>
-
.*会尽可能多地吃字符,直到最后一个满足条件的</tag>。
2. 懒惰匹配:.*?
在量词后面再加一个 ?,就变成“懒惰”(即最多满足一次):
-
*?:尽可能少的 0 次或多次 -
+?:尽可能少的 1 次或多次 -
??:尽可能少的 0 或 1 次 -
{n,m}?:在 n~m 之间,尽量少
改写上面的例子:
string pattern = @"<tag>.*?</tag>";
Match m = Regex.Match(input, pattern);
Console.WriteLine(m.Value);
匹配结果:
<tag>content</tag>
三、用量词写几个常见“格式”:
1. 简单日期:yyyy-MM-dd
^\d{4}-\d{2}-\d{2}$
- 不考虑合法性,只看格式
2. 用户名:字母开头,后面 3~15 位字母数字下划线
^[A-Za-z]\w{3,15}$
-
[A-Za-z]:首字符必须是字母 -
\w{3,15}:后面 3~15 个字母数字下划线 - 总长度:4~16
C#:
string pattern = @"^[A-Za-z]\w{3,15}$";
bool ok = Regex.IsMatch("User_001", pattern);
3. 整数和小数
简单版本的“非负整数或小数”:
^\d+(\.\d+)?$
-
\d+:至少一位数字 -
(\.\d+)?:可选的小数部分(.+ 至少一位数字)
匹配:0、123、3.14、0.5
不匹配:.、.5、3.(如果你想放宽,可以调整)。
四、锚点:决定“匹配的是不是整串”
锚点(Anchor)是一类特殊的“零宽”匹配,只匹配“位置”,不消耗字符。
1)^:开头,$:结尾
默认情况下:
-
^匹配字符串的开头; -
$匹配字符串的结尾。
示例:
^abc // 匹配以 "abc" 开头的字符串
abc$ // 匹配以 "abc" 结尾的字符串
^abc$ // 字符串只能是 "abc"
Regex.IsMatch("abc123", @"^abc"); // True
Regex.IsMatch("123abc", @"abc$"); // True
Regex.IsMatch("xabcx", @"^abc$"); // False
2. 表单校验一定要写 ^ 和 $
// 不严谨
Regex.IsMatch("abc2025-12-18xyz", @"\d{4}-\d{2}-\d{2}");
// True,只要“包含”符合格式的子串就通过
// 严谨
Regex.IsMatch("abc2025-12-18xyz", @"^\d{4}-\d{2}-\d{2}$");
// False,整个字符串不是完整日期
3. 字符类里的 ^ 意义完全不同
^abc // 锚点:开头
[^abc] // 取反:匹配任何不是a、b、c的字符
-
^在[]外:开头锚点 -
^在[]里且在首位:表示“取反”,方括号内的字符任意组合的反面
五、单词边界:\b
\b 是“单词边界”(word boundary),匹配“从一个 \w 字符到一个非 \w 字符的边界”。
例子:
string text = "cat scat category";
string pattern = @"\bcat\b";
MatchCollection matches = Regex.Matches(text, pattern);
foreach (Match m in matches)
{
Console.WriteLine(m.Value);
}
输出:
cat
解析:
-
"cat"前后都是边界(左边是开头,右边是空格),满足\b。 -
"scat"中的cat左边是s,属于\w,不会被\bcat\b匹配。 -
"category"中的cat右边是e,也是\w,也不符合。
六、多行模式(Multiline)与单行模式(Singleline)
C# 中用 RegexOptions 可以控制 ^ / $ 和 . 的行为。
1. RegexOptions.Multiline:多行模式
默认情况:
string text = "first\nsecond\nthird";
string pattern = @"^second$";
Console.WriteLine(Regex.IsMatch(text, pattern)); // False
因为:
-
^和$在默认模式下只匹配整个字符串起始和结尾,不会感知行。
多行模式开启后:
bool ok = Regex.IsMatch(
text,
pattern,
RegexOptions.Multiline
);
Console.WriteLine(ok); // True
此时:
-
^/$会匹配每一行的开头/结尾(以\n作为换行)。
2. RegexOptions.Singleline:单行模式 / DOTALL
默认情况下:
-
.不匹配换行符。
string text = "line1\nline2";
string pattern = @".*";
Match m1 = Regex.Match(text, pattern);
Console.WriteLine(m1.Value); // "line1"
开启 Singleline 后:
Match m2 = Regex.Match(text, pattern, RegexOptions.Singleline);
Console.WriteLine(m2.Value); // "line1\nline2"
此时:
-
.会匹配包括换行在内的任何字符。
总结一下:
-
Multiline:影响^/$,让它们感知“行” -
Singleline:影响.,让.能匹配换行
它们可以一起用:
var regex = new Regex(
pattern,
RegexOptions.Multiline | RegexOptions.Singleline
);
结语
点个赞,关注我获取更多实用 C# 技术干货!如果觉得有用,记得收藏本文