很久以前就知道正则表达式的重要性,但一直都只是会基本的使用。
基本语法
\d 匹配数字
\D 匹配非数字
\w 匹配字符
\W 匹配非字符
\s 匹配任何空白字符 包括空格制表符 换页符等
等效于[\f\n\r\t\v]
\S 匹配任何非空白符
. 匹配除\n意外的任何字符
[]匹配括号中任意字符 也可以[a-c]
[^] 匹配除括号中任意字符
{n}匹配n次
{n,}至少匹配那次
{n,m} n-m次
?零次或一次匹配
+一次或多次匹配
*零次或多次匹配
^匹配字符串或行开始
$匹配字符串或行结束
\A匹配字符串开始处
\z匹配字符串末尾处?
\Z匹配字符串末尾处,或位于换行符之前?
\b匹配一个边界,即字与空格的位置?
\B非字边界匹配?
\n换行符
\r回车符
\t制表符
\v垂直制表符
\f换页符
\nnn匹配一个8进制ASCII
\xnn匹配一个15进制ASCII
\unnn匹配4个16进制的Unicode
\c+大写字母 匹配ctrl+大写字母的控制符
a(?:b|c) == ab|ac?
a(?=b|c) == ab|ac?
a(?!b|c) == ab|ac?
x|y
其它
组与非捕获组
string x = "Live for nothing,die for something";
string y = "Live for nothing,die for somebody";
Regex r = new Regex(@"^Live ([a-z]{3}) no([a-z]{5}),die \1 some\2$");
Console.WriteLine("x match count:" + r.Matches(x).Count);//1
Console.WriteLine("y match count:" + r.Matches(y).Count);//0
//正则表达式引擎会记忆“()”中匹配到的内容,作为一个“组”,并且可以通过索引的方式进行引用。表达式中的“\1”,
用于反向引用表达式中出现的第一个组,即粗体标识的第一个括号内容,“\2”则依此类推。
string x = "Live for nothing,die for something";
Regex r = new Regex(@"^Live for no([a-z]{5}),die for some\1$");
if (r.IsMatch(x))
{
Console.WriteLine("group1 value:" + r.Match(x).Groups[1].Value);//输出:thing
}
//获取组中的内容。注意,此处是 Groups[1],因为 Groups[0]是整个匹配的字符串,即整个变量 x 的内容。
string x = "Live for nothing,die for something";
Regex r = new Regex(@"^Live for no(?<g1>[a-z]{5}),die for some\1$");
if (r.IsMatch(x))
{
Console.WriteLine("group1 value:" + r.Match(x).Groups["g1"].Value);//输出:thing
}
//可根据组名进行索引。使用以下格式为标识一个组的名称(?<groupname>…)。
string x = "Live for nothing nothing";
Regex r = new Regex(@"([a-z]+) \1");
if (r.IsMatch(x)) {
x = r.Replace(x, "$1");
Console.WriteLine("var x:" + x);//输出:Live for nothing
}
//删除原字符串中重复出现的“nothing”。在表达式之外,使用“$1”来引用第一个组,下面则是通过组名来引用:
string x = "Live for nothing nothing";
Regex r = new Regex(@"(?<g1>[a-z]+) \1");
if (r.IsMatch(x))
{
x = r.Replace(x, "${g1}");
Console.WriteLine("var x:" + x);//输出:Live for nothing
}
string x = "Live for nothing";
Regex r = new Regex(@"^Live for no(?:[a-z]{5})$");
if (r.IsMatch(x)){
Console.WriteLine("group1 value:" + r.Match(x).Groups[1].Value);//输出:(空)
}
//在组前加上“?:”表示这是个“非捕获组”,即引擎将不保存该组的内容。
贪婪与非贪婪
正则表达式的引擎是贪婪,只要模式允许,它将匹配尽可能多的字符。通过在“重复描述字符”(*,+)后 面添加“?”,可以将匹配模式改成非贪婪。
string x = "Live for nothing,die for something";
Regex r1 = new Regex(@".*thing");
if (r1.IsMatch(x))
{
Console.WriteLine("match:" + r1.Match(x).Value);//输出:Live for nothing,die for something
}
Regex r2 = new Regex(@".*?thing");
if (r2.IsMatch(x))
{
Console.WriteLine("match:" + r2.Match(x).Value);//输出:Live for nothing
}
回溯与非回溯
使用“(?>…)”方式进行非回溯声明
string x = "Live for nothing,die for something";
Regex r1 = new Regex(@".*thing,");
if (r1.IsMatch(x))
{ Console.WriteLine("match:" + r1.Match(x).Value);//输出:Live for nothing,
}
Regex r2 = new Regex(@"(?>.*)thing,");
if (r2.IsMatch(x))//不匹配
{ Console.WriteLine("match:" + r2.Match(x).Value);
}
//在 r1 中,“.*”由于其贪婪特性,将一直匹配到字符串的最后,随后匹配“thing”,但在匹配“,”时失败,此时引擎将回溯,并在“thing,”处匹配成功。
//在 r2 中,由于强制非回溯,所以整个表达式匹配失败。
正向预搜索 方向预搜索
正声明 “(?=…)”,负声明 “(?!…)”
@”\d{4}(?= used)”表示必须保证在四位数字的后面必须紧跟着“ used”
@”\d{4}(?! used)”表示四位数字之后不能跟有“ used”
@”(?<=used:)\d{4}”表示在 4 位数字之前必须紧跟着“used:”
@”(?
十六进制字符范围
正则表达式中,可以使用 “\xXX” 和 “\uXXXX” 表示一个字符(”X” 表示一个十六进制数)形式字符范 围:
\xXX 编号在 0 到 255 范围的字符,比如:空格可以使用 “\x20” 表示。
\uXXXX 任何字符可以使用 “\u” 再加上其编号的 4 位十六进制数表示,比如:汉字可以使用 “[\u4e00-\u9fa5]”表示。
择一匹配
(ab|xy)表示匹配ab或匹配xy
c#命名空间
1.System.Text.RegularExpressions 包含了正则表达式,以及实用正则表达式的各种方法。
2.MatchCollection 包含了一个正则表达式找到的所有匹配项。
3.Match 包含了一次匹配中所有匹配的文本
4.GroupCollection 包含了一次匹配中的所有分组
5.Group 包含一个分组集合中一个组的细节
6.CaptureCollection类 包含一个组的所有Capture对象
7.Capture 返回组内一次捕捉所匹配的字符串
8.RegexCompilationInfo 提供了把Regex编译为一个独立程序集所需的细节
RegexOption
1. IgnoreCase 忽略大小写
2. RightToLeft从右到左查找输入字符串,默认是从左到右
3. None
4. MultiLine指定了^和$可以匹配的开头和结尾,以及字符串的开头和结尾,也就是说,使用换行符分割,每一行都能够得到不同的匹配,但是字符"."仍然不匹配换行符
5. SingleLine规定特殊字符"."匹配任一字符,包括换行符。默认情况下"."不匹配换行符,场和MultiLine一起使用
Regex
IsMatch
//判断是否匹配
//静态方法
Regex.IsMatch(...);
//使用Regex实例
Regex myRegex = new Regex(...)
myRegex.IsMatch(...)
Match
创建并发挥Match对象来提供匹配信息
成员变量 | 解释 |
---|---|
Success | 发挥匹配是否成功 |
Value | 发挥实际匹配文本的副本 |
Length | 发挥实际匹配文本的长度 |
Index | 显示匹配文本在目标中的其实位置(0开始) |
Groups | |
Group | |
NextMatch | 返回应用于目标的下一个匹配 |
Result | |
Synchronized | 返回一个新的,与当前Match完全一样的Match对象,适合多线程使用 |
Captures |
Mathcs
返回一组Match对象
replace
//替换
public static string Regex.Replace(string input, string pattern, string replacement);
public static string Regex.Replace(string input, string pattern, string replacement, RegexOptions options);
Split
//切割
public static string[] Split(string input, string replacement);
Escape(string)
接收一个字符串并返回此字符串的副本,其中的元字符会进行转义。
Unescape(string)
接收一个字符串并返回此字符串的副本,同时去掉它的的反斜线
Regex.Empty
返回代表匹配失败的Match对象
Regex.CompileToAssembly
允许用户创建一个assembly(装配件),封装正则表达式。
缓存
为了避免每次调用静态方法都需要创建一个临时的Regex对象,然后启用,.Net默认提供15个正则表达式。
Regex.CacheSize = 15;