正则表达式实例1:电子邮件地址正则匹配
部分 | 规则 | 正则表达式 |
---|---|---|
1 | 大小写字母,0-9,(.),(+)或(_)。 | [A-Za-z0-9._+]+ |
2 | 符号@ | @ |
3 | 大小写字母和数字 | [A-Za-z0-9]+ |
4 | 符号(.) | . |
5 | 以com或edu或org或net结尾 | (com |
合 | 规则 | [A-Za-z0-9._+]+@[A-Za-z]+.(com |
当试图从头开始编写任何正则表达式时,最好先制定一个步骤列表,具体列出目标字符串的外观。
常用的正则表达式符号
符号 | 含义 | 例子 | 例子匹配 |
---|---|---|---|
* | 匹配前面的字符,子表达式或括号字符,0次或多次 | a*b* | aaaa,bbbb,aabb |
+ | 匹配前面的字符,子表达式或括号字符,1次或多次 | a+b+ | ab,aaaaab,abbbb |
[] | 匹配括号里面的任意字符 | [A-Z]* | APPLE,BAG,ORANGE |
() | 分组表达式 | (a*b)* | aaabaab,abaaab,ababaaaaab |
{m,n} | 匹配前面的字符,子表达式或括号字符,m-n次 | a{2,3}b{2,3} | aaabb,aabb,aabbb,aaabbb |
[^] | 匹配任何不在括号内的单个字符 | [^A-Z] | apple,lowercase,qwerty |
| | 匹配由“I”分隔的任何字符,字符串或子表达式 | b(a|i|e)d | bad,bid,bed |
. | 匹配任何单个字符(包括符号,数字,空格等) | b.d | bad,bzd,b d,b$d |
^ | 字符或子表达式出现在字符串的开头 | ^a | apple,asdf,a |
\ | 转义字符 | .\|\ | .|\ |
$ | 把它匹配到字符串的末尾 | [A-Z]*[a-z]*$ | ABCabc,zzzyx,Bob |
?! | 不包含 |
分组
分组在正则表达式中用()表示,分组有两个作用:
- 将某些规律看成一组,然后进行组别级的重复,如匹配b出现偶数次:(bb)*
- 分组后可以通过向后引用,简化表达式。
例1,匹配IP地址,
- 简单形式:\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}
.\d{1,3}是重复的,于是我们可以把.\d{1,3}当成一组,再重复3次。表达式如下:
- \d{1,3}(.\d{1,3}){3}
例2:匹配<title>.*</title>标签:
- 简单形式:<title>.*</title>
可以看出上面表达式有两个title,完全一样,我们可以将title分成一组,再向后引用,简写成:
- <(title)>.*</\1>
对于分组而言,整个表达式永远算作第0组。本例中<(title)>.*</\1>是第0组,然后从左至右,一次分组编号。因此(title)是第1组。
使用\1这种语法,可以使用某组的文本内容。
对于上面IP正则匹配的例子\d{1,3}(.\d{1,3}){3},里边的\d{1,3}是重复的。若使用向后引用,改写成(\d{1,3})(.\1){3},现分析表达式:(\d{1,3})为第一组,(.\1)为第二组,在第二组里通过\1语法引用了第一组的文本内容。
向后引用,引用的仅仅是文本内容,而不是正则表达式!
也就是说,组中的内容一旦匹配成功,向后引用,引用的就是匹配成功的内容,引用的是结果,而不是表达式。因此(\d{1,3})(.\1){3}这个表达式实际上匹配的是4段都相同的IP地址,诸如111.111.111.111之类。
断言
断言只是条件,帮你找到真正需要的字符串,本身并不匹配
所谓断言,就是指明某个字符串前边或后边将会出现满足某种规则的字符串。
断言类型 | 表达式 | 作用 |
---|---|---|
零宽度正先行断言 | (?=exp) | 匹配表达式exp前面的字符串 |
零宽度负先行断言 | (?!exp) | 匹配后面不是exp的位置 |
零宽度正后发断言 | (?<=exp) | 匹配表达式exp后面的字符串 |
零宽度正后发断言 | (?<!exp) | 匹配前面不是表达式exp的位置 |
例3:匹配获取<title>我爱我家</title>(Python)
import re
testStr= "<title>我爱我家</title>"
reg = r"(?<=<title>).*(?=</title>)"
reObj = re.compile(reg)
print(reObj.findall(string))