用了正则表达式很久,但一直都用得很皮毛,很多时候都去网站搜匹配的正则代码。终究觉得这不是一个事儿,静下心来好好缕缕吧。
正则表达式干嘛的?
正则表达式就是记录文本规则的代码(没有数学运算)。
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。
推荐入门文章,自己看去
http://deerchao.net/tutorials/regex/regex.htm#introduction
如果您已经有所了解,可以直接看我下面的笔记。这是一篇总结性的文章,不具备原创性。
重要的几个概念
1.元字符
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
\b 指定一个位置,单词分隔符
* 会被解释成任意的字符串
2.字符转义(\)
查找元字符本身,用\ 进行转义。
3.重复
下面是正则表达式中所有的限定符(指定数量的代码,例如*,{5,12}等):
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
指的是单个字符的重复;而下面的提到的分组,是指多个字符(即字符串)的重复。
4.字符类
5.分枝条件(|)
解决 or 的问题,通俗的说法,匹配A或B (A|B)。
6.分组
描述字符串的重复匹配规则。即,重复多个字符又该怎么办?
你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了。如:(\d{1,3}\.){3}:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
7.反义
查找除**以外的字符时,这时需要用到反义。
8.后向引用
用于重复搜索前面某个分组匹配的文本。即引用前面已经匹配的内容。
怎么引用匹配的文本呢?
小括号指定一个子表达式后(分组),匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,生成规则是:
- 分组0对应整个正则表达式
- 实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
- 你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.
9.零宽断言
查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置(本身不表示任何字符),这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
分为四类:
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
(?!exp)零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
(?<!exp)零宽度负回顾后发断言,断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
贪婪与懒惰
贪婪匹配:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
语法:正则表达式中包含能接受重复的限定符,即为贪婪匹配模式。如:a.*b,用它来搜索aabab的话,它会匹配整个字符串aabab
懒惰匹配:与贪婪相反,*** ... 匹配尽可能少的字符。
语法:只要在限定符它后面加上一个问号?。a.*?b,用它来搜索aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
懒惰限定符
代码/语法 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
平衡组/递归匹配
.NET 中正则表达式处理选项
下面是.Net中常用的正则表达式选项:
名称 | 说明 |
---|---|
IgnoreCase(忽略大小写) | 匹配时不区分大小写。 |
Multiline(多行模式) | 更改^和$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) |
Singleline(单行模式) | 更改.的含义,使它与每一个字符匹配(包括换行符\n)。 |
IgnorePatternWhitespace(忽略空白) | 忽略表达式中的非转义空白并启用由#标记的注释。 |
ExplicitCapture(显式捕获) | 仅捕获已被显式命名的组。 |
注释
小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
一些杂碎的体会
常用的正则表达式语法
常用的正则表达式