编程中经常要处理字符串。其中,在提取子字符串方面,可以由正则表达式来完成。
正则表达式
所谓正则表达式,便是一串以字符串形式表现的匹配规则。通过该规则,可以从目标字符串中提取出所需的子字符串。
在C#中,正则表达式的写法大致如下:
1 | string pattern = @"\w+"; |
因为表达式内有多种转义字符,所以必须加上
@前缀。
调用正则
想要使用正则表达式,就必须要调用对应的方法。在C#中,正则表达式相关的方法,都被放在System.Text.RegularExpressions命名空间内。
匹配
C#提供了用于储存匹配对象的类Match和MatchCollection,后者为前者的集合。
这里的匹配对象不是字符串类型,但可以用Match.Value获取其字符串。
两者使用方法如下表所示:
| 比较 | Match |
MatchCollection |
|---|---|---|
| 内容 | 第一个匹配对象 | 多个匹配对象 |
| 方法 | Regex.Match() |
Regex.Matches() |
规则
正则表达式有一套统一的匹配规则,不受语言类型的限制。
普通字符
可以直接用普通字符串来做匹配规则。
1 | string pattern = @"王一凡"; |
上述规则,可以从目标字符串中提出"王一凡"子字符串。
匹配字符
可以用对应的匹配字符来匹配字符串。
常用的匹配字符如下表:
| 匹配字符 | 描述 | 规则 | 匹配 |
|---|---|---|---|
| . | 匹配任意字符 | a.e | "have ate"中的"ave"和"ate" |
| \t | 匹配制表符 | \w+\t | "Hello\t"中的"Hello\t" |
| \n | 匹配换行符 | \w+\n | "Yes\n"中的"Yes\n" |
| \w | 匹配字母、数字和下划线 | \w+ | "So What"中的"So"和"What" |
| \W | 匹配非字母、数字和下划线 | \W+ | "Room##1"中的"##" |
| \s | 匹配空白字符 | \w+\s | "I am light Jack!"中的"I "、"am "、"light " |
| \S | 匹配非空白字符 | \S+ | "I am light Jack!"中的"I"、"am"、"light"、"Jack!" |
| \d | 匹配十进制数字符 | \d+ | "源自2019"中的"2019" |
| \D | 匹配非十进数制字符 | \D+ | "源自2019"中的"源自" |
| [char1-char2] | 匹配对应范围字符 | [0-9]+ | "祖国70周年生日快乐!"中的"70" |
此外,可以通过在[char1-char2]内添加^来取反。如:[^0-9]+可匹配"祖国70周年生日快乐!"中的"祖国"、"周年生日快乐!"。
定位点
利用定位点,正则表达式可以限定匹配位置。
常用定位点如下表所示:
| 定位点 | 描述 | 规则 | 匹配 |
|---|---|---|---|
| ^ | 定位字符串开头 | ^\d+ | "0538-6388-5364"中的"0538" |
| $ | 定位字符串结尾 | \d+$ | "0538-6388-5364"中的"5364" |
| \b | 定位单词边界 | \w+\b | "have ate"中的"have"和"ate" |
限定符
可以为正则表达式添加各种限定。
常用限定符如下表:
| 限定符 | 描述 | 规则 | 匹配 |
|---|---|---|---|
| * | 匹配上一个元素零次或多次 | \d*\.\d | "w.385"中的".3" |
| + | 匹配上一个元素一次或多次 | \d+ | "0538-6388-5364"中的"0538"、"6388"和"5364" |
| ? | 匹配上一个元素零次或一次 | \w?\d+ | "Room123"中的"m123" |
| {n} | 匹配上一个元素n次 | \w{2} | "Air"中的"Ai" |
| {n,} | 匹配上一个元素至少n次 | \w{2,} | "Air"中的"Air" |
| {n,m} | 匹配上一个元素至少n次,至多m次 | \w{1,3} | "123ABC"中的"ABC" |
分组构造
可以为匹配的对象分组,以便于区分不同的信息。
具体可以用Match.Groups获取组的集合。
分组的具体用法有:
| 分组构造 | 描述 | 规则 | 匹配 |
|---|---|---|---|
| (regex) | 创建分组 | (\w+)\d+ | —— |
| (?=regex) | 判断是否满足条件 | \d+(?=[0-4]) | "0538-6388-5364"中的"0"、3"、"3"、"3"和"4" |
| (?!regex) | 判断是否不满足条件 | \d+(?![0-4]) | "0538-6388-5364"中的"5"、8"、"6"、"88"、"5"和"6" |
| (?:regex) | 定义非捕获组 | (?:\w+)\d+ | —— |
实例
下面提供两个正则表达式的应用实例。
匹配邮箱
有时候需要从一段较为杂乱的字符串中获取有效的邮箱,用正则表达式可以很方便的完成。
1 | string pattern = @"(\w+)@(\w+\.com)"; |
上述匹配规则可以匹配以字母、数字和下划线为名的邮箱。
匹配浮点数
有时会把数字储存在字符串内,为了提取方便,可以使用正则表达式来完成。
1 | string pattern = @"([1-9]+|0(?=\.))\.\d+"; |