编程中经常要处理字符串。其中,在提取子字符串方面,可以由正则表达式来完成。
正则表达式
所谓正则表达式,便是一串以字符串形式表现的匹配规则。通过该规则,可以从目标字符串中提取出所需的子字符串。
在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+"; |