C#正则表达式的基本语法

前言

正则表达式的匹配模式由一系列数字、文字、运算符、字符等的字符组成,根据自己需求设计对应的模式,实现分析、匹配的操作。本文将对正则表达式组成语法进行讲解。

语法规则

正则表达式构建的匹配模式由转义字符、字符类、定位符、分组构造、限定符、反向引用构造、备用构造、替换、杂项构造等组成。

1、特殊字符:正则表达式中已经具有一定特殊意义的字符

字符 描述
^ 匹配输入字符串的开始位置
$ 匹配输入字符串的结束位置
\ 将特殊字符变为普通的字符;指定预定义字符集;定义断言
? 匹配前面的字符零次或一次
+ 匹配前面的字符一次或多次
* 匹配前面的字符零次或多次
. 匹配出换行符外的任意一个字符
- 表示字符的匹配范围
| 匹配以竖线字符分隔的任何一个字符

示例:

cs 复制代码
#region ^
// 模式 ^136
  string pattern = @"^136";
  Console.WriteLine(string.Format("字符串是否以136开头:{0}", Regex.IsMatch("1380000001", pattern)));
// 输出
字符串是否以136开头:false
#endregion

#region $
// 模式 $136
  string pattern = @"$136";
  Console.WriteLine(string.Format("字符串是否以136开头:{0}", Regex.IsMatch("13800010136", pattern)));
// 输出
字符串是否以136结束:true
#endregion

#region -
// 模式 ^[A-Za-z]+$
  Regex regex = new Regex(@"^[A-Za-z]+$");
  Console.WriteLine(string.Format("字符串是否全为英文字母:{0}",regex.IsMatch("Hello123")));
// 输出
字符串是否全为英文字母:false
#endregion

2、转义字符:将特殊字符变为普通的字符。下表列举了一些常用的转义字符:

字符 描述
\a 警报
\b 退格
\e Esc
\f 换页符
\n 换行符
\r 回车符
\t 水平制表符

示例:

cs 复制代码
#region \n
// 模式 \n(\w+) 匹配换行符+)");
  string content = "\nHello\nWorld";
  MatchCollection matches = Regex.Matches(content,@"\n(\w+)");
  foreach (Match match in matches)
  {
    Console.WriteLine(string.Format("{0}",match.Value));
  }
// 结果
Hello
World
#endregion

3、定位符:根据字符位置来进行匹配。下表列举一些常用的定位符:

字符 描述
\A 匹配字符串的开始位置
\Z 匹配字符串的结尾位置或结尾换行之前的位置
\z 匹配字符串的结尾位置
\G 匹配上一个匹配结束的位置
\b 匹配字符的开始或结束的位置
\B 匹配字符的中间位置

示例:

cs 复制代码
#region \A
// 模式 \A136
  string pattern = @"\A136";
  Console.WriteLine(string.Format("字符串是否以136开头:{0}", Regex.IsMatch("136SayHello", pattern)));
// 输出
字符串是否以136开头:true
#endregion

#region \B 
// 模式 \Bin\w+
// \B 不在单词边界处开始匹配
// in  匹配子字符串"in"
// \w+ 匹配一个或多个单词字符
  string content = "starting running ending";
  foreach(Match match in Regex.Matches(content, @"\Bin\w+"))
  {
     Console.WriteLine(" {0} 在字符位置 {1}", match.Value, match.Index);
  }
// 输出
ing 在字符位置 5
ing 在字符位置 13
#endregion

4、字符类:定义一组字符,其中的任一字符均可出现在输入字符串中以便成功匹配。

字符 描述
[character_group] 正字符组指定一个字符列表,任何一个字符可出现在输入字符串中以便进行匹配。
[first-last] 正字符组一个字符范围
[^character_group] 负字符组指定一个字符列表,任何字符不得出现在输入字符串中以便进行匹配。
[^first-last] 负字符组一个字符范围
\w 与任何单词字符匹配
\W 任何非单词字符
\p{name} name 指定的 Unicode 通用类别或命名块中的任何单个字符匹配
\P{name} 与不在 name 指定的 Unicode 通用类别或命名块中的任何单个字符匹配
\s 与空白字符匹配
\S 与任何非空白字符匹配
\d 与任何十进制数字匹配
\D 匹配不是十进制数的任意字符

示例:

cs 复制代码
#region [first-last]
// 模式 \b[A-Z]\w*\b
// \b  在单词边界处开始。
// [A-Z]  匹配从 A 到 Z 的所有大写字符。
// \w*  匹配零个或多个单词字符。
// \b  与字边界匹配。
string content = "A work B Hard Zero Time";
foreach (Match match in Regex.Matches(content, @"\b[A-Z]\w*\b"))
{
    Console.WriteLine("{0}", match.Value);
}
// 输出
A
B
Hard
Zero
Time
#endregion

#region \D
// 模式 ^\D\d{1,5}\D*$
// ^  从输入字符串的开头部分开始匹配。
// \D  匹配非数字字符。
// \d{1,5}  匹配一到五个十进制数字。
// \D*  匹配零个、一个或多个非十进制字符。
// $  匹配输入字符串的末尾部分。
  string content = "A1039C";
  Console.WriteLine("{0}", Regex.IsMatch(content, @"^\D\d{1,5}\D*$"));
// 输出
True
#endregion

5、限定符:指定输入中必须存在字符、组或字符类的多少实例才能找到匹配项。

字符 描述
{n} 恰好匹配 n 次
{n,} 至少匹配 n 次
{n,m} 匹配 n 到 m 次
*? 匹配零次或多次
+? 匹配一次或多次
?? 匹配零次或一次
{n}? 前面的元素恰好匹配 n 次
{n,?} 前面的元素至少匹配 n 次,但次数尽可能少
{n,m}? 匹配上一元素 n 次到 m 次,但次数尽可能少

示例:

cs 复制代码
#region {n,m}
// 模式 ^\D\d{1,3}\D*$
// ^  从输入字符串的开头部分开始匹配。
// \D  匹配非数字字符。
// \d{1,3}  匹配一到五个十进制数字。
// \D*  匹配零个、一个或多个非十进制字符。
// $  匹配输入字符串的末尾部分。
  string content = "B30590C";
  Console.WriteLine("{0}", Regex.IsMatch(content, @"^\D\d{1,3}\D*$"));
// 输出
False
#endregion

6、分组

字符 描述
(subexpression) 捕获匹配的子表达式
(?<name>subexpression) 捕获匹配的子表达式,并允许你按名称或编号访问它
(?<name1 -name2>subexpression) 平衡组定义将删除以前定义的组和存储的定义
(?: subexpression) 不会捕获与子表达式匹配的子字符串
(?imnsx-imnsx:subexpression) 应用或禁用子表达式中指定的选项
(?= subexpression) 定义零宽度正预测先行断言
(?! subexpression) 定义零宽度负预测先行断言
(?> subexpression) 定义零宽度正回顾后发断言

示例:

cs 复制代码
#region (?> subexpression)
// 模式 (?<=\b31)\d{2}\b
// (?<=\b31)  以数字位数"31"开头,则继续匹配。
foreach (Match match in Regex.Matches("3124 2024 1140 3119", @"(?<=\b31)\d{2}\b"))
{
    Console.WriteLine(match.Value);
}
// 结果
// 24
// 19
#endregion
#region (subexpression)
// 模式 (?<=\b31)\d{2}\b
// (?<=\b31)  以数字位数"31"开头,则继续匹配。
foreach (Match match in Regex.Matches("3124 2024 1140 3119", @"(?<=\b31)\d{2}\b"))
{
    Console.WriteLine(match.Value);
}
// 结果
// 24
// 19
#endregion

7、替换

字符 描述
$number 替换按组 number 匹配的子字符串。
${name} 包括替换字符串中由 (name) 指定的命名组所匹配的最后一个子字符串。
$$ 包括替换字符串中的单个"$"文本
$& 包括替换字符串中整个匹配项的副本。
$` 包括替换字符串中的匹配项前的输入字符串的所有文本。
$' 包括替换字符串中的匹配项后的输入字符串的所有文本。
$+ 包括在替换字符串中捕获的最后一个组。
$_ 包括替换字符串中的整个输入字符串。

小结

正则表达式是处理字符串的强大工具,拥有独特的语法和独立的处理引擎。本文通过一些示例来介绍正则表达式组成模式的常用字符及语法。

相关推荐
code bean2 分钟前
【LangChain】少样本提示(Few-Shot Prompting)实战指南
开发语言·python·langchain
AI人工智能+电脑小能手5 分钟前
【大白话说Java面试题 第42题】【JVM篇】第2题:JVM内存模型有哪些组成部分?
java·开发语言·jvm·面试
yqcoder5 分钟前
深入理解 JavaScript:什么是可迭代对象 (Iterable)?
开发语言·javascript·网络
破阵子443289 分钟前
如何用 Claude Code 等 Agent 工具操作 MATLAB(支持代码编写及 Simulink)
开发语言·matlab
AI人工智能+电脑小能手12 分钟前
【大白话说Java面试题 第43题】【JVM篇】第3题:GC分为哪两种?Young GC 和 Full GC有什么区别?
java·开发语言·jvm·后端·面试
步步为营DotNet21 分钟前
.NET 11 中 Microsoft.Extensions.AI 在智能后端推理与决策优化的应用
云原生·c#·.net
Bear on Toilet22 分钟前
【JSON-RPC远程过程调用组件库】测试报告
开发语言·软件测试·后端·自动化脚本
星恒随风24 分钟前
C语言链表详解:从单链表到双向链表
c语言·开发语言·链表
lsx20240625 分钟前
《Foundation 均衡器:深入解析其工作原理与应用领域》
开发语言
常常有25 分钟前
中间件与依赖系统:构建高效 Web 后端的双重利器
开发语言·python·中间件·fastapi