正则表达式快速入门小栗子

写在前面

在写本文之前,我也是对正则完全没接触,在做爬虫的时候看别人用正则匹配数据很酷炫,感觉像乱码一样很烦很烦。然而万事开头难,勇于尝试才是解决之道。本文不跟你多逼逼,直接拿栗子上手三十分钟入门正则。

小栗子:

\bhi\b

精确查找hi这个单词

\b 是正则表达式规定的一个元字符,代表单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格,标点符号或者换行来分隔的,但是 /b 并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置

\bhi\b.*\bXSS\b

匹配一个单词hi,然后是任意个任意字符(非换行符),最后是XSS这个单词。这里 . 是另一个元字符,匹配除了换行符以外的任意字符。 同样是元字符,不过它代表的不是字符,也不是位置,而是数量,它指定 前面的内容可以连续重复任意次使整个表达式得到匹配。因此,.* 连在一起就意味着 任意数量的不包含换行的字符。

0\d\d-\d\d\d\d\d

匹配以0开头,然后是两个数字,然后是一个连字符“-”,最后是五位数字。\d 是个新的元字符,匹配一位数字,- 不是元字符,只匹配它本身。

\ba\w*\b

匹配以字母 a 开头的字符串。

\w 是匹配字母或数字或下划线或汉字等。

\b\w{6}\b

匹配刚好6个字符的字符串。{n}表示重复n次,属于限定符。

\d+

匹配一个或者更多连续的数字。

这里的+是和 类似的元字符,不同的是 是匹配重复任意次(可能是0次),而+则匹配重复一次或更多次。

^\d{5,12}$

匹配五位到十二位的数字。

元字符^(和数字6在同一个键位)和$都匹配一个位置。^匹配你要用来查找的字符串的开头,美元符匹配结尾。这两个元字符在验证输入的内容非常有用。

(?0\d{2}[) -]?\d{8}匹配几种格式的电话号码,例如:(010)23333333和022-23333333首先是一个转义字符 (,因为(和)都是元字符,它可能出现0次或1次( ? ),然后是一个0,后面跟着两个数字(\d{2}),然后是)或-或空格中的一个,它出现0次或1次( ? ),最后是八个数字(\d{8})。
0\d{2}-\d{8}|0\d{3}-\d{7}匹配两种以连字符分隔的数字,例010-23333333和0376-2333333| 能把不同的规则分隔开,可以实现正则表达式中的分支条件。使用分支条件时,要注意各个条件的顺序。
(\d{1,3}.){3}\d{1,3}匹配一个简单的IP地址。\d{1,3}匹配一到三位的数字,(\d{1,3}.){3},在之前的基础上加一个点(转义.)然后把这个整体重复三次,最后再加上一个一到三位的数字(\d{1,3})。不幸的是,它也可以匹配233.233.233.256这种不可能存在的 IP 地址。如果能使用算数比较的话,或许就简单的解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的 IP 地址: ((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。
]+>匹配用尖括号括起来的以 a 开头的字符串。这里讲一下反义,有时候需要查找不属于某个能简单定义的字符类的字符。如下:表3.常用的反义代码代码/语法说明\W匹配任意不是字母,数字,下划线,汉字的字符\S匹配任意不是空白符的字符\D匹配任意非数字的字符\B匹配不是单词开头或结束的位置[^x]匹配除了x以外的任意字符[^aeiou]匹配除了aeiou这几个字母以外的任意字符
\b(\w+)\b\s+\1\b用来匹配重复的字符串。例: xss xss这个表达式首先是一个单词,也就是单词的开始处和结束处之间的多于一个的字母或者数字(\b(\w+)\b),这个字符串会被捕获到编号为1的分组中,然后是一个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。这里讲的是后向引用:使用一个小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其他程序中做进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左往右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
表4.常用分组语法分类代码/语法说明捕获(exp)匹配exp,并捕获文本到自动命名的组里(?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。
(?).(?=<\/\1>)匹配不包含属性的简单HTML标签里的内容。(?<=<(\w+)>)指定这样的前缀:被尖括号括起来的字符串(例如:

),然后是 .

(任意的字符串),最后是一个后缀(?=<\/\1)。注意后缀里的 \/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀是

的话,后缀就是

了。整个表达式匹配的就是

之间的内容。(不包括前缀后缀本身)
a.b匹配最长的以a开头,以b结尾的字符串。但是,当搜索aabab时,它会匹配aabab,也就是说会匹配最长的字符串,这被称为贪婪匹配。
a.
?b匹配最短的,以a开始,以b结束的字符串。这被称为懒惰匹配,只有在它后面加一个问号?。表5.懒惰限定符代码/语法说明*?重复任意次,但尽可能少重复+?重复1次或更多次,但尽可能少重复??重复0次或1次,但尽可能少重复{n,m}?重复n到m次,但尽可能少重复{n,}?重复n次以上,但尽可能少重复

C:\Windows

匹配C:\Windows

如果想查找元字符本身的话,我们可以用 \ 来取消这些字符的特殊意义,属于转义字符。

[.?!]

匹配标点符号(. 或 ? 或 ! )

[]可以指定一个字符的范围,像[0-9]代表的含义和 \d 完全一致:匹配一位数字。

(?0\d{2}[) -]?\d{8}

匹配几种格式的电话号码,例如:(010)23333333和022-23333333

首先是一个转义字符 (,因为(和)都是元字符,它可能出现0次或1次( ? ),然后是一个0,后面跟着两个数字(\d{2}),然后是)或-或空格中的一个,它出现0次或1次( ? ),最后是八个数字(\d{8})。

0\d{2}-\d{8}|0\d{3}-\d{7}

匹配两种以连字符分隔的数字,例010-23333333和0376-2333333

| 能把不同的规则分隔开,可以实现正则表达式中的分支条件。使用分支条件时,要注意各个条件的顺序。

(\d{1,3}.){3}\d{1,3}

匹配一个简单的IP地址。

\d{1,3}匹配一到三位的数字,(\d{1,3}.){3},在之前的基础上加一个点(转义.)然后把这个整体重复三次,最后再加上一个一到三位的数字(\d{1,3})。不幸的是,它也可以匹配233.233.233.256这种不可能存在的 IP 地址。如果能使用算数比较的话,或许就简单的解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的 IP 地址: ((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。

]+>

匹配用尖括号括起来的以 a 开头的字符串。

这里讲一下反义,有时候需要查找不属于某个能简单定义的字符类的字符。

\b(\w+)\b\s+\1\b

用来匹配重复的字符串。例: xss xss

这个表达式首先是一个单词,也就是单词的开始处和结束处之间的多于一个的字母或者数字(\b(\w+)\b),这个字符串会被捕获到编号为1的分组中,然后是一个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。这里讲的是后向引用:使用一个小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其他程序中做进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左往右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

(?=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。

(?<=\s)\d+(?=\s)

匹配以空白符间隔的数字(不包括空白符)。

使用了以上两个断言,断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。

\b\wq(?u)\w \b

匹配包含后面不是字母u的字母q的字符串。

(?!exp)被称为零宽度负预测先行断言,断言此位置的后面不能匹配表达式exp,再例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字。\b((?!abc)\w)+\b匹配不包含连续字符串abc的字符串。

(?<=(\w+)>).*(?=<\/\1>)

匹配不包含属性的简单HTML标签里的内容。

(?<=<(\w+)>)指定这样的前缀:被尖括号括起来的字符串(例如:

),然后是 .*(任意的字符串),最后是一个后缀(?=<\/\1)。注意后缀里的 \/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀是

的话,后缀就是

了。整个表达式匹配的就是

之间的内容。(不包括前缀后缀本身)

a.*b

匹配最长的以a开头,以b结尾的字符串。

但是,当搜索aabab时,它会匹配aabab,也就是说会匹配最长的字符串,这被称为贪婪匹配。

a.*?b

匹配最短的,以a开始,以b结束的字符串。

这被称为懒惰匹配,只有在它后面加一个问号?。

最后

感谢 deerchao 的教程,原文地址 当然,说好的三十分钟入门,可能你会花了很多时间,如果没有看懂,那没事,试着像我一样把正则表达式加文档自己码一遍也许会理解更深哟。

下面放几个很实用的链接吧。

正则表达式在线测试 当然里面有好多常见的正则,可以直接伸手哦。

MSDN正则快速参考 这个就不用多说了,稳得一批。

我们一直都向往,面朝大海,春暖花开。 但是几人能做到,心中有爱,四季不败?