正则表达式
正则表达式 提供了一种字符串的匹配模式(pattern)
总体来说和js的正则没什么区别,注意一下彼此的使用方法即可。。。。
1. [] # 代表一个原子表 [a] # 匹配字母a [abc] # 匹配a或b或c [a-z] # 匹配任意一位小写字母 [A-Z] # 匹配任意一位大写字母 [a-zA-Z] # 匹配任意一位字母 [0-9] # 匹配数字 2. ^ # 以什么作为开头 ^a # 匹配以字母a做为开头的一串字符 ^abc # 匹配字母abc作为开头的 ^[abc] # 匹配以a或b或c作为开头的 [^abc] # 匹配以a或b或c以外作为开头的 [^a-zA-Z] # 匹配除了a-z和A-Z以外的 3. $ # 以.. 作为结尾(同^组合来用) ^[1][3-8][0-9]{9}$ # 匹配手机号 以1作为开头 第二位是3-8 后九位是0-9 ^[1][345678][0-9]{9}$ # 同上 4. {m} # 表示匹配前面表达式的m次 abc{2} # 匹配ab和两次c 1[a-z]{2} # 1和两个小写字母 5. {m,n} # 表示匹配前面的表达式的m到n次 [1-9][0-9]{4,10} # 4到10位 6. {m,} # 匹配前面的表达式至少m次 7. ? # 表示前面的表达式可有可无 [1-9][0-9]? # 匹配年龄1-99岁 前面1-9岁后面可有可无 [1-9][0-9]{0,1} # 同上 8. . # 匹配除了换行符\n以外的任意一个字符 .{2} # 匹配除了换行符以外的任意两个字符 9. * # 匹配前面的表达式 0次到多次 .* # 匹配除了换行符以外的任意字符任意次 贪婪模式 .{0,} #同上 .*? # 匹配除了换行符以外的任意字符任意次 拒绝贪婪模式 10. + # 表示 匹配前面的数量一次到多次 .+ # 匹配除了换行符以外的任意字符至少一次 贪婪模式 .{1,} .+? #匹配除了换行符以外的任意字符至少一次 拒绝贪婪模式 11. () # 1, 代表一个单元 2, 子存储 12. | # 或 a|b #匹配a或b ab(c|d) # 匹配ab c或d
正则的修正符
# re.I 不区分大小写 # re.M 改变^和$的作用 # re.S 改变.的行为 # 可用于匹配带换行的
特殊意义的字符
\d [0-9] # 匹配数字 \D [^0-9] # 匹配除数字以外的 \w [A-Za-z0-9_] # 匹配字母数字下划线 \W [^0-9A-Za-z_] # 匹配除了字母数字下划线的其他字符 \s # 匹配空白字符 包括空格、制表符、换页符等等。包括[\n\r\t]。 \S # 匹配非空白字符 [^\n\r\t]
正则常用的函数
import re
(1) re.findall(pattern,string,flags)
匹配所有,以列表的形式来返回 当匹配失败时候返回空列表
例如:
myStr = """ <a href="http://www.baidu.com">百度</a> <a href="http://www.taobao.com">淘宝</a> <a href="www.taobao.com">淘宝2</a> <A href="http://www.id97.com">电影网站</A> <a href="http://www.dj.com">京东</a> """ dataList = re.findall("<a href=\"http://.*?\">.*?</a>",myStr,re.I) # 1245 不区分大小写 dataList = re.findall("<[aA] href=\"http://.*?\">.*?</[aA]>",myStr,re.S) # 1245不区分大小写 # re.S 匹配换行符 包含\n dataList = re.findall("<a href=\"http://.*?\">.*?</a>",myStr,re.S) # 125 不要第三个
(2) re.match(pattern,string,flags)
只匹配一次,使用group取值,匹配成功返回对象 匹配失败返回None
res = re.match("[a-zA-z]{2,3}","Aaaaa") print(res) # <_sre.SRE_Match object; span=(0, 3), match='Aaa'> print(res.group()) # 返回匹配的值 Aaa 匹配了三次
注意:
- 从第一位开始匹配
- 只匹配一次
注意:
[a-z] 可以用来匹配任意位置上的小写字母: "…a…" ^[a-z] 只能匹配以小写字母为行首的行: "a…" [a-z]$ 只能匹配以小写字母为行尾的行: "…a"^ [a-z]$ 应该只能匹配只有一个小写字母的行: "a"
(3) re.search(pattern,string,flags)
匹配成功返回对象 匹配失败None
注意:
- 只匹配一次
- 只要字符串中包含就可以
(4) re.sub(pattern,repl,myStr,count,flags)/re.subn 正则的替换
返回替换后的结果 \\n表示当前查找的第n个括号里面的值
sub和subn的区别: sub只返回替换的结果 subn返回替换后的结果和次数
实例:
# 换成em 标签 myStr = "<b>我是b</b><i>我是i</i><strong>加粗strong</strong>" myStr2 = "1970/01/02" # 将b换成em 即 <em>第三方</em> data = re.sub("<b>(.*?)</b>", "<em>\\1</em>", myStr) print(data) # <em>我是b</em> # 将所有 换成<em>第三方</em> # data = re.sub("<b>(.*?)</b><i>(.*?)</i><strong>(.*?)</strong>", "<em>\\1</em><em>\\2</em><em>\\3</em>", myStr) data = re.sub("<.*?>(.*?)</.*?>", "<em>\\1</em>", myStr) print(data) # 02日01月970年 data = re.sub("([0-9]+)/([0-9]+)/([0-9]+)", "\\3日\\2月970年", myStr2) data = re.subn("(\d+)/(\d+)/(\d+)", "\\3日\\2月970年", myStr2) print(data)
(5) re.split(pattern,string,maxsplit,flags) 正则的拆分
将字符串拆分成列表
实例:
myStr = "1jjj1h$hhh1hjj&j1" print(re.split("\W",myStr)) # 数字字母下划线以外的字符作为拆分的条件 默认拆分全部 ['1jjj1h', 'hhh1hjj', 'j1'] print(re.split('\d',myStr,1)) # 数字作为拆分的条件 只拆分一次 ['', 'jjj1h$hhh1hjj&j1'] print(re.split("[a-z]",myStr,flags=re.I)) # 字母作为拆分条件 拆分所有
(6) re.finditer(pattern,string,flags) 以迭代器的形式返回结果
匹配所有
实例:
myStr = "abcDMdefg23456uuii" reIter = re.finditer("[a-z]",myStr,re.I) print(reIter) # <callable_iterator object at 0x0000005AB0807710> print(next(reIter).group()) # a print(next(reIter).group()) # b print(next(reIter).group()) # c print(next(reIter).group()) # D print(next(reIter).group()) # M
(7) re.compile(pattern,flags)
执行效率高 将正则和字符串分开
实例:
import re path = r"C:\Users\fanzone\Desktop\Python笔记\code\day12_正则\豆瓣.html" file = open(path,"r",encoding="utf-8") data = file.read() file.close() # re.DOTALL == re.S re.IGNORECASE == re.I re.MULTILINE == re.M pattern = re.compile("<a href=\"https://book\.douban\.com/subj\ ect/[0-9]+/\">(.*?)</a>",re.DOTALL|re.IGNORECASE|re.MULTILINE) # 编译正则返回正则对象 print(pattern.findall(data)) # 返回列表