本帖最后由 创造命运 于 2014-4-6 21:40 编辑
一、什么是正则表达式
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。
正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
作用:用于专门操作字符串。
特点:用于一些特定的符号来表示一些代码操作,以简化代码书写。
二、常用符号
1) 元字符(metacharacter)
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
例如\bhi\b表式以h开头,以i结束的单词。
\bhi\b.*\bLucy\b的意思:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词。
\b并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置。
2) 转义字符
\\ 反斜线字符
\t 制表符
\n 回车符
\f 换页符
\a 报警字符(打印它的效果是电脑嘀一声)
\r 回车
\v 竖向制表符
\e Escape
\A 字符串开头(类似^,但不受处理多行选项的影响)
\Z 字符串结尾或行尾(不受处理多行选项的影响)
\z 字符串结尾(类似$,但不受处理多行选项的影响)
\G 当前搜索的开头
例如:www\.baidu\.com匹配www.baidu.com
C:\\Windows匹配C:\Windows。
3) 字符类
[abc] a、b或c
[^abc] 任何字符,除了a、b或c
[a-zA-Z] a到z或A到Z
[a-e[p-t]] a到e或p到t(另一种写法:[a-ep-t])
4) 反义
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符
例子:\S+匹配不包含空白符的字符串。
<a[^>]+>匹配用尖括号括起来的以a开头的字符串。
5) 重复
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
例子:0\d{2}-\d{8}:前面\d必须连续重复匹配2次(8次)
Windows\d+匹配Windows后面跟1个或更多数字
^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab
(第一到第三个字符)和ab(第四到第五个字符)。
为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,
因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高
的优先权——The match that begins earliest wins。
三、分枝条件
正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。
例如:0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,
8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
使用分枝条件时,要注意各个条件的顺序。
例如:\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。
如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。
原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
四、分组
用小括号来指定子表达式(也叫做分组)。
例如表达式:(\d{1,3}\.){3}\d{1,3} 这是一个简单的IP地址匹配表达式。
要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句
号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字(\d{1,3})。
不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址。如果能使用算术比较的话,或许能简单地解决这个问题,
但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址:
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。
理解这个表达式的关键是理解"2[0-4]\d|25[0-5]|[01]?\d\d?" : 2[0-4]\d为200到249; 25[0-5]为250到255; [01]?\d\d?为0到199
五、处理选项
IgnoreCase(忽略大小写) 匹配时不区分大小写。
Multiline(多行模式) 更改^和$的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串
的开头和结尾匹配。(在此模式下,$的精确含意是:匹配\n之前的位置以及字符串结束
前的位置.)
Singleline(单行模式) 更改.的含义,使它与每一个字符匹配(包括换行符\n)。
IgnorePatternWhitespace(忽略空白) 忽略表达式中的非转义空白并启用由#标记的注释。
ExplicitCapture(显式捕获) 仅捕获已被显式命名的组。
一个经常被问到的问题是:是不是只能同时使用多行模式和单行模式中的一种?答案是:不是。这两个选项之间没有任何关系,
除了它们的名字比较相似(以至于让人感到疑惑)以外。
六、笔记来源
我只记下了我能够看到懂并理解的部分。其他关于后向引用、零宽断言负、向零宽断言、平衡组/递归匹配等等什么的,
目前的我看了,也不是很理解,所以决定暂时先不管了。
网址:http://www.jb51.net/tools/zhengze.html#mission
http://blog.csdn.net/shengfeixiang/article/details/8820673
关于正则表达式语言元素的MSDN在线文档http://msdn.microsoft.com/zh-cn/library/az24scfc.aspx |
|