正则表达式30分钟入门教程

上一篇 / 下一篇  2011-01-25 14:43:45 / 个人分类:automation

正则表达式 (Regular expression)
材料链接
http://deerchao.net/tutorials/regex/regex.htm

元字符
常用元字符:
代码说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
例子
匹配QQ号必须为5到12位数字——^\d{5,12}$
字符转义
如果想查找元字符本身时,就需要转义。使用“\”
重复
常用限定符:
代码/语法说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
字符类
在方括号里列出它们,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或
?或!)。
我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[az0-
9A-Z_]也完全等同于\w(如果只考虑英文的话)。
下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}
“(”和“)”也是元字符,后面的分组节里会提到,所以在这里需要使用转义。
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或
02912345678等。我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一
个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字
(\d{8})。
分支条件
正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用
"|"把不同的规则分隔开。
\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?)。
反义
常用的反义代码
代码/语法说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符
例子
\S+匹配不包含空白符的字符串
<a[^>]+>匹配用尖括号括起来的以a开头的字符串。
后向引用
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的
分组的组号为1,第二个为2,以此类推。后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表
分组1匹配的文本。
分组0对应整个正则表达式\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 你也可以自己指定
子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成
'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以
使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
常用分组语法:
分类代码/语法说明
捕获(exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成
(?'name'exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释(?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供
注释让人阅读
零宽断言
(?=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。
例子
你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里
面添加逗号的部分:((?<=\d)\d{3})+\b,用它对1234567890进行查找时结果是234567890
负向零宽断言
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位
数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![az])\
d{7}匹配前面不是小写字母的七位数字。
例子
(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(<?(\w+)>)指定了这样
的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/
\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一
组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是
<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。
注释
小括号的另一种用途是通过语法(?#comment)来包含注释。
例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
贪婪与懒惰
以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜
索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配
aab(第一到第三个字符)和ab(第四到第五个字符)。
懒惰限定符:
代码/语法说明
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2020-03-15  
1234567
891011121314
15161718192021
22232425262728
293031    

数据统计

  • 访问量: 1573
  • 日志数: 14
  • 建立时间: 2010-10-22
  • 更新时间: 2011-02-11

RSS订阅

Open Toolbar