re 正则表示式
正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
一、正则表达式的作用
1、给字符串进行模糊匹配,
2、对象就是字符串
二、字符匹配(普通字符,元字符)
1.普通字符:数字字符和英文字母和自身匹配
2.元字符:. ^ $ * + ? {} [] () |
re.方法("规则","匹配的字符串")
. 匹配任意一个字符,除了
换行符
三、匹配规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
'.' 默认匹配除
之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行 '^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r "^a" , "
abc
eee" ,flags = re.MULTILINE) '$' 匹配字符结尾,或e.search( "foo$" , "bfoo
sdfsf" ,flags = re.MULTILINE).group()也可以 '*' 匹配 * 号前的字符 0 次或多次,re.findall( "ab*" , "cabb3abcbbac" ) 结果为[ 'abb' , 'ab' , 'a' ] '+' 匹配前一个字符 1 次或多次,re.findall( "ab+" , "ab+cd+abb+bba" ) 结果[ 'ab' , 'abb' ] '?' 匹配前一个字符 1 次或 0 次 '{m}' 匹配前一个字符m次 '{n,m}' 匹配前一个字符n到m次,re.findall( "ab{1,3}" , "abb abc abbcbbb" ) 结果 'abb' , 'ab' , 'abb' ] '|' 匹配|左或|右的字符,re.search( "abc|ABC" , "ABCBabcCD" ).group() 结果 'ABC' '(...)' 分组匹配,re.search( "(abc){2}a(123|456)c" , "abcabca456c" ).group() 结果 abcabca456c 'A' 只从字符开头匹配,re.search( "Aabc" , "alexabc" ) 是匹配不到的 '' 匹配字符结尾,同$ 'd' 匹配数字 0 - 9 'D' 匹配非数字 'w' 匹配[A - Za - z0 - 9 ] 'W' 匹配非[A - Za - z0 - 9 ] 's' 匹配空白字符、 、
、
, re.search( "s+" , "ab c1
3" ).group() 结果 ' ' '(?P<name>...)' 分组匹配 re.search( "(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})" , "371481199306143242" ).groupdict( "city" ) 结果{ 'province' : '3714' , 'city' : '81' , 'birthday' : '1993' } |
四、演示示例
findall 用法
ps1:
1 #找出字符串中的数字 2 re.findall('d+',"alex22jack33rain32sdfsd4") #执行这段代码
执行结果:
1 ['22', '33', '32', '4']
ps2:
1
2
|
findall 找到匹配,返回所有匹配部分的列表( re.findall( "a..x" , "adsxaeyxsk19" ) #找到所有以a开头,以x结尾的字符 |
执行结果:
1 ['adsx', 'aeyx']
ps3:
1 re.findall("I","I am LIST") #匹配所有I的字符
执行结果:
1 ['I', 'I']
. 的作用:匹配任意的意思(一个点代表一个字符,有多个字符,就用多个点代替)
1 re.findall("a..x","adsfaeyxsk19") #匹配以a开头,以x结尾的字符
执行结果:
1 ['aeyx']
^ 只能在字符串的开头去匹配
ps1:
1 re.findall("^a..x","adsxaeyxsk19") #^ 只能在字符串的开头去匹配
执行结果:
1 ['adsx']
ps2:
1 re.findall("^I","I am LIST") #匹配开头是I的字符
执行结果:
1 ['I']
以d开头,*匹配所有是d的
1 re.findall("^d*","dddddddd1ksdfgjdddddd")
执行结果:
1 ['dddddddd']
$ 匹配以什么结尾的字符
1 re.findall("a..x$","adsxaeyxsk19arrx") #这里表示匹配以x结尾的字符
执行结果:
1 ['arrx']
* + ? {} 匹配重复的符号(贪婪匹配)
ps1:
1 re.findall("d*","adsxaeddddddddddddyxsk19arrx") #* 紧挨着的字符,可以匹配无穷次
执行结果:
1 ['', 'd', '', '', '', '', 'dddddddddddd', '', '', '', '', '', '', '', '', '', '', '']
ps2:
1 re.findall("alex*","asdhfalexxx") #*匹配以alex中,x结尾的所有x ,因为*代表可以重复的符号
执行结果:
1 ['alexxx']
ps3:
1 re.findall("alex+","asdhfalexxx") #+匹配以alex中,x结尾的所有x,因为+代表可以重复的符号
执行结果:
1 ['alexxx']
ps4:
1 re.findall("alex*","asdhfale") # *可以代表什么都没有
执行结果:
1 ['ale']
ps5:
1 re.findall("alex?","asdhfalexxx") #?代表0次或1次
执行结果:
1 ['alex']
ps6:
1 re.findall("alex?","asdhfale") #?代表0次或1次
执行结果:
1 ['ale']
{} 想取多少次,就取多少次
{0,} ==*
1 re.findall("alex{1,}","asdhfalexx")
执行结果:
1 ['alexx']
{1,}==+
1 re.findall("alex{0,}","asdhfalexx")
执行结果:
1 ['alexx']
{0,1}==?
1 re.findall("alex{0,1}","asdhfalexx")
执行结果:
1 ['alex']
{6} 重复6次
1 re.findall("alex{6}","asdhfalexxxxxx")
执行结果:
1 ['alexxxxxx']
{0,6} 重复1,2,3,4,5,6
1 re.findall("alex{0,6}","asdhfalexx")
执行结果:
1 ['alexx']
[ ] 字符集 等于或的作用
ps1:
1 re.findall("x[yz]","xyuuuu")
执行结果:
1 ['xy']
ps2:
1 re.findall("x[yz]","xyuuxzuu") #或的作用
执行结果:
1 ['xy', 'xz']
ps3:
1 re.findall("x[yz]p","xypuuxzpuu") #或的作用
执行结果:
1 ['xyp', 'xzp']
ps4:
1 re.findall("q[a-z]*","quo") #匹配以a-z结束的字符
执行结果:
1 ['quo']
ps5:
1 re.findall("q[a-z]*","quogjgkjjhk") #匹配以a-z所有的字符
执行结果:
1 ['quogjgkjjhk']
ps6:
1 re.findall("q[a-z]*","quogjgkjjhk9") #匹配以a-z所有的字符
执行结果:
1 ['quogjgkjjhk']
ps7:
1 re.findall("q[0-9]*","quogjgkjjhk9") #匹配以q开头挨着的0-9的字符,所以只有q
执行结果:
1 ['q']
ps8:
1 re.findall("q[0-9]*","q899uogjgkjjhk9") #匹配以q开头挨着的0-9的字符,所以只有q899
执行结果:
1 ['q899']
[^] 就是不是他的都匹配上
1 re.findall("q[^a-z]","q213") #只能匹配a-z之外的字符集
执行结果:
1 ['q2']
元字符 就是让有意义的变成没有意义,让无意义的变成有意义
ps1:
1 re.findall("d","12+(34*6+2-5*(2-1))") #匹配任何十进制的数
执行结果:
1 ['1', '2', '3', '4', '6', '2', '5', '2', '1']
ps2:
1 re.findall("d+","12+(34*6+2-5*(2-1))") #匹配任何十进制的数
执行结果:
1 ['12', '34', '6', '2', '5', '2', '1']
ps3:
1 re.findall("[0-9]+","12+(34*6+2-5*(2-1))") #匹配所有0-9的字符
执行结果:
1 ['12', '34', '6', '2', '5', '2', '1']
ps4:
1 re.findall("[D]+","12+(34*6+2-5*(2-1))") #匹配所有非数字
执行结果:
1 ['+(', '*', '+', '-', '*(', '-', '))']
字符匹配
ps1:
1 re.findall("D+","hello world") #D匹配非数字字符
执行结果:
1 ['hello world']
ps2:
1 re.findall("S+","hello world") #S 匹配非空的字符
执行结果:
1 ['hello', 'world']
ps3:
1 re.findall("w","hello world_") #w 匹配任何字母数字字符
执行结果:
1 'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd', '_']
ps4:
1 re.findall("www.baidu","www/baidu") #匹配任意字符
执行结果:
1 ['www/baidu']
ps5:
1 re.findall("www.baidu","wwwobaidu") #匹配任意字符
执行结果:
1 ['wwwobaidu']
ps6:
1 re.findall("www.baidu","www baidu") ##匹配任意字符,但只有 除外
执行结果:
1 []
ps7:
1 re.findall("www.baidu","www.baidu") #去除元字特殊功能
执行结果:
1 ['www.baidu']
ps8:
1 re.findall("www*baidu","www*baidu") #有特殊功能,可以转义
执行结果:
1 ['www*baidu']
匹配中间带有空格的字符
ps1:
1 re.findall(r"I","I am LIST") re的r =\ ,就相当转义两次
执行结果:
1 ['I']
ps2:
1 re.findall("I\b","I am LIST") #\转义字符
执行结果:
1 ['I']
ps3:
python解释器\ 两个,re转义\ 两个,所以是\\ 四个
1 re.findall("c\\l","abclerwt") #同时匹配c和l
执行结果:
1 ['c\l']
ps4:
1 re.findall(r"c\l","abclerwt") #同时匹配c和l
执行结果:
1 ['c\l']
| 就是或的意思
ps1:
1
|
re.findall(r "ka|b" , "sdjkasf" ) #匹配ka或b |
执行结果:
1 ['ka']
ps2:
1 re.findall(r"ka|b","sdjkbsf") 匹配ka或b
执行结果:
1 ['b']
ps3:
1 re.findall(r"ka|b","sdjka|bsf") #匹配ka或b
执行结果:
1 ['ka', 'b']
元字符分组 ()
ps1:
1 re.findall("(abc)+","abcabc" )
执行结果:
1 ['abc']
ps2:
1 re.findall("(abc)+","abccccc" )
执行结果:
1 ['abc']
search 函数会在字符串内查找模式匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以
通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
ps1:
1
|
re.search( "(?P<name>w+)" , "abcccc" ) |
执行结果:
1 <_sre.SRE_Match object; span=(0, 6), match='abcccc'> #匹配成功了,返回的就是对象
ps2:
1 re.search("d+","sdfas34sdfg15")
执行结果:
1 <_sre.SRE_Match object; span=(5, 7), match='34'>
ps3:
1 re.search("d+","sdfas34sdfg15").group() #d+ 是匹配数字
执行结果:
1 '34'
ps4:
1 re.search("(?P<name>[a-z]+)","alex36wusir34xialv33") #<>的作用就是把内容进行分组
执行结果:
1 <_sre.SRE_Match object; span=(0, 4), match='alex'>
ps5:
1 re.search("(?P<name>[a-z]+)","alex36wusir34xialv33").group() #group()匹配的内容取出来
执行结果:
1 'alex'
ps6:
1 re.search("[a-z]*","alex36wusir34xialv33").group() #匹配包含a-z的内容
执行结果:
1 'alex'
ps7:
1 re.search("[a-z]+","alex36wusir34xialv33").group() #匹配包含a-z的内容,+号的作用就是重复
执行结果:
1 'alex'
ps8:
1 re.search("(?P<name>[a-z]+)d+","alex36wusir34xialv33").group("name") #通过分组,可以给group传叁数,找出你想要的信息
执行结果:
1 'alex'
ps9:
1 re.search("(?P<name>[a-z]+)(?P<age>d+)","alex36wusir34xialv33").group("age") #通过分组找出你想要的信息
执行结果:
1 '36'
match
ps1:
1 re.match('a','abc').group() #同search,不过尽在字符串开始处进行匹配
执行结果:
1 'a'
ps2:
1 re.match("d+","56alex36wusir34xialv33")
执行结果:
1 <_sre.SRE_Match object; span=(0, 2), match='56'>
ps3:
1 re.match("d+","56alex36wusir34xialv33").group()
执行结果:
1 '56'
split 分割
ps1:
1 ret=re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割 2 print(ret)
执行结果:
1 ['', '', 'cd']
ps2:
1 re.split(" ","hello abc def") #匹配中间带有空格的
执行结果:
1 ['hello', 'abc', 'def']
ps3:
1 re.split("[ l]","hello abcldef")
执行结果:
1 ['he', '', 'o', 'abc', 'def']
ps4:
1 re.split("[ |]","hello abc|def")
执行结果:
1 ['hello', 'abc', 'def']
ps5:
1 re.split("[ab]","asdabcd")
执行结果:
1 ['', 'sd', '', 'cd']
ps6:
1 re.split("[ab]","abc") #以自己为分界点,进行分隔,有的就以‘’ 填充
执行结果:
1 ['', '', 'c']
sub 替换
ps1:
1 re.sub("d+","A","jaskd4234ashdjf5423") #把所有数字替换为A(4234替换为A)
执行结果:
1 'jaskdAashdjfA'
ps2:
1 re.sub("d","A","jaskd4234ashdjf5423") #把所有数字替换为A(4234替换为AAAA)
执行结果:
1 'jaskdAAAAashdjfAAAA'
ps3:
1 ret=re.sub('d','abc','alvin5yuan6',1) #把5替换成abc
执行结果:
1 alvinabcyuan6
ps4:
1 re.sub("d","A","jaskd4234ashdjf5423",4) #指定替换次数 4,只替换前面4个数字
执行结果:
1 'jaskdAAAAashdjf5423'
subn 第一个匹配元组,第二个匹配次数
ps1:
1 ret=re.subn('d','abc','alvin5yuan6') #第一个匹配元组,第二个匹配次数 2 print(ret)
执行结果:
1 ('alvinabcyuanabc', 2)
ps2:
1 re.subn("d","A","jaskd4234ashdjf5423") #第一个匹配元组,第二个匹配次数,8次
执行结果:
1 ('jaskdAAAAashdjfAAAA', 8)
compile 编译
ps1:
1 com=re.compile("d+") #编译好了一次,下次再用,直接就调用他,不用再编译,提高匹配速度 2 com.findall("fjlksad234hfjksd3421") #可以匹配多次
执行结果:
1 ['234', '3421']
ps2:
1 obj=re.compile('d{3}') 2 ret=obj.search('abc123eeee') 3 print(ret.group())
执行结果:
1 123
finditer(迭代器)当数据非常多的时候,他会把数据存在迭代器中,不会放在内存中,用一条处理一条。
ps1:
1 re.finditer("d","sdfgs6345dkflfdg534jd")
执行结果:
1 <callable_iterator object at 0x01093710> #返回的是迭代器对象
ps2:
1 ret=re.finditer("d","sdfgs6345dkflfdg534jd") 2 next(ret).group() #拿到结果 3 '6' 4 next(ret).group() 5 '3' 6 next(ret).group() 7 '4' 8 next(ret).group() 9 '5' 10 next(ret).group() 11 '5' 12 next(ret).group() 13 '3' 14 next(ret).group() 15 '4'
补充内容:
ps1:
1 ret=re.findall('www.(baidu|oldboy).com','www.oldboy.com') 2 print(ret)
执行结果:
1 ['oldboy'] #这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ps2:
1 re.findall("www.(baidu|163).com","www.baidu.com")
执行结果:
1 ['baidu'] #这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ps3:
1 re.findall("www.(baidu|163).com","dfdsssfwww.baidu.comdsfsfs")
执行结果:
1 ['baidu'] #这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ps4:
1 re.findall("www.(baidu|163).com","dfdsssfwww.163.comdsfsfs")
执行结果:
1 ['163'] #这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ps5:
1 ret=re.findall('www.(?:baidu|oldboy).com','www.oldboy.com') 2 print(ret)
执行结果:
1 ['www.oldboy.com']
ps6:
1 re.findall("www.(?:baidu|163).com","dfdsssfwww.163.comdsfsfs") #如果要匹配置全部网址,取消他的优化级,在前面加?:
执行结果:
1 ['www.163.com']
生产环境常见正则示例:
1、匹配手机号
1 phone_num = '13001000000' 2 a = re.compile(r"^1[d+]{10}") 3 b = a.match(phone_num) 4 print(b.group())
2、匹配IPv4
1 # 匹配IP地址 2 ip = '192.168.1.1' 3 a = re.compile(r"(((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5])).){3}((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))$") 4 b = a.search(ip) 5 print(b)
3、匹配E-mail
1 email = '630571017@qq.com' 2 a = re.compile(r"(.*){0,26}@(w+){0,20}.(w+){0,8}") 3 b = a.search(email) 4 print(b.group())