一、
就本质而言,正则表达式(或re)是一种小型的、高度专业化的编程语言,(在python中)它内嵌在python中,并通过re模块实现。正则表达式模式被编译成一系列得字节码,然后由用c语言编写的匹配引擎执行。
字符匹配(普通字符,元字符):
1 普通字符:大多数字符和字母都会和自身匹配
re.findall('alvin','wangzhaoqian')
['alvin']
2元字符:. ^ $ * + ? {} [] | () \ 共11个
“ . " 代表通配符,指除了"\n"以外所有的都能匹配
"^" 代表以。。。开头的意思
"$" 代表以。。。结尾
关于重复功能的有四个: * + ? {}
" * " 代表0到无穷次 即[0,+oo]
" + " 代表1到无穷次,即[1,+oo]
" ? " 代表0次或1次,即[0,1]
"{}" 代表自己定次数,例如
{0,} 等价于* ;{1,}等价于 + ;{0,1} 等价于 ? ; {6} 只能重复6次 ; {1,6} 指重复1到6之间的哪一次都行。
注意:前面的 * + ?都是贪恋匹配,也就是尽可能的匹配,但是,后面加?号后使其变成惰性匹配
元字符之: ^ $ * + ? {}
1 import re 2 ret = re.findall('a..in','helloalvin') 3 print(ret) #['alvin']
4
5 ret = re.findall('^a...n','alvinhelloworld') 6 print(ret) #['alvin']
7
8 ret = re.findall('a...n$','alvinhellowoarldn') 9 print(ret)# ['arldn']
10
11 ret = re.findall('abc','abcccc') 12 print(ret) #['abc']
13
14 ret = re.findall('abc*','abcccc') #贪婪匹配[0,+oo]
15 print(ret) #['abcccc']
16
17 ret = re.findall('abc+','abcccc') #贪婪匹配 [1,+oo]
18 print(ret) #['abcccc']
19
20 ret = re.findall('abc?','abcccc') #[0,1]匹配一次或0次
21 print(ret) #['abc']
22
23 ret = re.findall('abc{1,4}','abccc') #匹配1次到4次之间出现的任意一次
24 print(ret) #贪婪匹配
25
26 ##----> 注意:前面的 * + ?都是贪恋匹配,也就是尽可能的匹配,但是,后面加?号后
27 # 使其变成惰性匹配
28
29 ret = re.findall('abc*?','abccccc') 30 print(ret) #['ab']
元字符之字集 [ ]:
1 import re 2 ret = re.findall('a[bc]d','acd') 3 print(ret) #['acd']
4
5 ret = re.findall('[a-z]','acd') #"-" 代表a到z的的所有字母
6 print(ret) #['a', 'c', 'd']
7
8 ret = re.findall('[.*+]','a.cd+') 9 print(ret) 10
11 ##在字符集里有功能的符号只有: - ^ \
12 ## "-" :在[]字符集中,指范围的意思
13 ## " ^ " :在[]的字符集中,是”非“ 的意思
14 ## " \ " : 在[]的字符集中,是转义字符
15 ## 在[]里面没有特殊符号,而且里面试”或“的关系,不过,只有上述三个除外
16
17 ret = re.findall('[1-9]','45dank8') 18 print(ret) #['4', '5', '8']
19
20 ret = re.findall('[^ab]','45danbk8') 21 print(ret) # ['4', '5', 'd', 'n', 'k', '8']
22
23 ret = re.findall('[\d]','45danbk8') 24 print(ret) #['4', '5', '8']
25
26 ret = re.findall('\([^()]\)','12+(34*6+2-5*(2-1))') 27 print(ret) # []
28
29 ret = re.findall('\([^()]*\)','12+(34*6+2-5*(2-1))') 30 print(ret) #['(2-1)']
元字符之转义符\
反斜杠后边去除特殊功能,比如\.
反斜杠后边跟普通字符实现特殊功能,比如\d
\d 批评日任何十进制数;它相当于类[0-9]]
\D匹配任何非数字字符;它相当于类[^0-9]
\s 匹配任何空白字符;它相当于类[\t\n\f\v]
\S匹配任何非空白字符;它下该党于类[^\t\n\f\v]
\w匹配任何字母数字字符;它相当于类[a-zA-Z0-9]
\W匹配任何非字母数字字符;它相当于类[^a-zA-Z0-9]
\b匹配一个特殊字符边界,比如空格,&,#等
1 import re 2 ret = re.findall('I\b','I am LIST') 3 print(ret)#[]
4
5 ret = re.findall(r'I\b','I am LIST') 6 print(ret) #['I']
先看看关于“ \” 的例子
1 import re 2 ret = re.findall('c\ l','abc\le') 3 print(ret) #[]
4
5 ret = re.findall('c\\ l','abc\le') 6 print(ret) #[]
7
8 ret = re.findall('c\\\\l','abc\le') 9 print(ret) # ['c\\l']
10
11 ret = re.findall(r'c\\l','abc\le') 12 print(ret) #['c\\l']
之所以选择\b是因为\b在ASCII表中是有意义的
1 m = re.findall('\bblow','blow') 2 print(m) #[]
3
4 m = re.findall(r'\bblow','blow') 5 print(m) #['blow']
元字符之分组
1 import re 2 ret = re.findall('(?:abc)+','abcabcabcabc') 3 print(ret) #['abcabcabcabc'] 4 ret = re.findall('(?:abc)','abcabcabcabc') 5 print(ret) #['abc', 'abc', 'abc', 'abc']
1 import re 2 m = re.findall(r'ad+','add') 3 print(m) #['add']
4 m = re.findall( '(ad)+','adadadad') #?????
5 print(m) #['ad']
6
7 ret = re.findall('(?P<id>\d{2})/(?P<name>\w{3})','23/com') 8 print(ret) #[('23', 'com')]
9
10 ret = re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com') 11 print(ret.group()) #23/com
12
13 #search匹配成功则返回,匹配不成功,不返回。而且search只会找满足第一个的元素
14
15 ret = re.search('(?P<id>[a-z]+)','alex23hah89beijing66') 16 print(ret) #<_sre.SRE_Match object; span=(0, 4), match='alex'>
17 print(ret.group()) #alex
18 ret = re.search('([a-z]+)','alex23hah89beijing66') 19 print(ret) 20 print(ret.group()) 21 #对比可知,?P<>没什么作用,它只是起个名字,放便用的时候取出来
22
23 ret = re.search('(?P<id>[a-z]+)\d+','alex23hah89beijing66').group() 24 print(ret) #alex23
25 ret = re.search('(?P<name>[a-z]+)\d+','alex23hah89beijing66').group('name') 26 print(ret) #alex
27
28
29 ret = re.search('(?P<name>[a-z]+)(?P<age>\d+)','alex23hah89beijing66') 30 print(ret.group('name')) #alex
31 print(ret.group('age')) #23
32
33 ret = re.search('((?P<name>[a-z]+)(?P<age>\d+))+','alex23hah89beijing66') 34 print(ret.group('name'),ret.group('age')) #?P<>只是给取了名字,以后做大数据是,方便调用
35 print(ret.group()) #alex23hah89beijing66
元字符之管道符 | 管道符:是“或”的意思
1 import re 2 ret =re.search('(ab|\d)','rabhdg8sd') 3 print(ret) # <_sre.SRE_Match object; span=(1, 3), match='ab'>
4 print(ret.group()) #ab
5
6 ret = re.findall(r'ka|b','sdjkbsf') 7 print(ret) #['b']
8
9
10 ret = re.findall(r'ka|b','sdjkasf') 11 print(ret) #['ka']
12
13 ret = re.findall(r'ka|b','sdjka|bsf') 14 print(ret) #['ka', 'b']
re模块的常用方法
1 ###--------------re模块的常用方法------------------------------------------
2 import re 3 #1
4 re.findall('a','alvin yuan') #返回所有满足匹配条件的结果,放在列表例
5 #2
6 re.search('a','alvin yuan').group() #函数会在字符串那日查找模式匹配,直到找到第一个匹配返回一个包
7 #通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回空
8 #3
9 re.match('a','abc').group() #同search,不过仅在字符串开始处进行匹配
10 #4
11 ret = re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割
12 print(ret) #['', '', 'cd']
13 #5
14 ret = re.sub('\d','abc','al8vin5yu4an7',2) #可以备注匹配几次
15 print(ret) #alabcvinabcyu4an7
16
17 ret = re.sub('\d','abc','al8vin5yu4an7',4) #从后面匹配的内容换成'abc',也就是置换
18 print(ret) #alabcvinabcyuabcanabc
19
20 ret = re.subn('\d','abc','alvin5yuan7') 21 print(ret) #('alvinabcyuanabc', 2) 返回匹配的次数
22 #6
23 obb= re.compile('\d{3}') #将规则封装成了一个对象,下面用的时候直接调用对象就好了,方便简单
24 ret=obb.search('abc123eeedd') 25 print(ret.group()) #123
26
27 ###-----------finfiter的用法-----------------------------
28 ret = re.finditer('\d','ds3sy4584as') 29 print(ret) #<callable_iterator object at 0x000001E82CDDCF98>
30 print(next(ret).group()) #3
31 print(next(ret).group()) # 4
32 ##返回的对象ret是一个可迭代对象,不用打印出来,用的时候打印一个,用next()方法
33
34 ##------------------注意--------”?:“的用法-----------------------------------------------
35
36 ret = re.findall('www.(baidu|oldboy).com','www.oldboy.com') 37 print(ret) #['oldboy'] 这是因为findall会游戏那把匹配结果的组里内容返回,如果想要匹配结果,取消权限即可
38 ret = re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') 39 print(ret) #['www.oldboy.com'] #通过 ?: 这两个字符,就取消的分组的优先级
40
41 ret = re.findall('www\.(?:baidu|oldboy)\.com','www.oldboy.com') 42 print(ret) #['www.oldboy.com'] 看来加不加 \ ,这里没关系