二十正则表达式(re模块)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二十正则表达式(re模块)相关的知识,希望对你有一定的参考价值。
re模块
正则表达式:
字符串模糊匹配
字符(普通字符、元字符)
普通字符:普通字母,字符
完全匹配
import re print(re.findall(‘chen‘,‘shuaigeshichen‘)) # ‘chen‘
元字符:$. ^ * + ? { } [ ] | ( ) \
模糊匹配
re常用方法:
# findall() 匹配所有符合规则对象(规则,匹配项),返回一个列表 # search() 只匹配一项,成功返回对象,失败返回None,通过对象.group取值(规则,匹配项) # match() 只匹配字符串开始位置,成功返回对象,失败返回None,通过对象.group取值(规则,匹配项) # split() 切分匹配项,(规则,匹配项,最大分割次数)想要保留分隔符的话就加分组() # sub() 匹配替换(规则:也就是要替换的内容,新的内容,原始内容) # subn() 也是替换,以元组形式返回,并且返回替换的次数 # compile() 编译: 先编译规则,拿到对象:obj = re.compile("\w+") 这样规则就给了obj, obj.findall("内容")就可以直接匹配 # finditer() 返回一个迭代器对象;如果匹配项特别大,推荐使用这个方法,一个个拿
单个字符匹配:
. 匹配除换行符以外的任意一个字符
print(re.findall(‘陈.‘,‘陈一,陈二,李三,陈六七‘)) # [‘陈一‘, ‘陈二‘, ‘陈六‘] print(re.findall(‘陈..‘,‘陈一,陈二,李三,陈六七‘)) # [‘陈一,‘, ‘陈二,‘, ‘陈六七‘]
^ 匹配字符串的开头部分
print(re.findall(‘^陈.‘,‘陈一,陈二,李三,陈六七‘)) # [‘陈一‘] print(re.findall(‘^陈..‘,‘陈一,陈二,李三,陈六七‘)) # [‘陈一,‘]
$ 匹配字符串的结束部分
print(re.findall(‘a..m‘,‘a陈一,a陈二m成,a李三j,a陈六m‘)) # [‘a陈二m‘, ‘a陈六m‘] print(re.findall(‘a..m$‘,‘a陈一,a陈二m,a李三j,a陈六m‘)) # [‘a陈六m‘]
重复匹配:
* 重复0到无穷次
print(re.findall(‘138\d*‘,‘1384561456,1561,138,14561‘)) # [‘1384561456‘, ‘138‘]
+ 重复1到无穷次
print(re.findall(‘138\d+‘,‘1384561456,1561,138,14561‘)) # [‘1384561456‘]
? 重复0到1次
print(re.findall(‘-?\d+‘,‘16,11,-8,61‘)) # [‘16‘, ‘11‘, ‘-8‘, ‘61‘]
{} 重复指定次
print(re.findall(‘\d{2}‘,‘1384561456,1561,138,14561‘)) # [‘13‘, ‘84‘, ‘56‘, ‘14‘, ‘56‘, ‘15‘, ‘61‘, ‘13‘, ‘14‘, ‘56‘]
\转义符:
1、反斜杠后边跟元字符去除特殊功能,比如\.
print(re.findall("\.com","baidu.com")) # [‘.com‘] 这里匹配规则的 . 只是个普通符合
2、反斜杠后边跟普通字符实现特殊功能,比如\d
\d 匹配任何十进制数; 它相当于 [0-9]。 \D 匹配任何非数字字符; 它相当于 [^0-9]。 \s 匹配任何空白字符; 它相当于 [ \t\n\r\f\v]。 \S 匹配任何非空白字符; 它相当于 [^ \t\n\r\f\v]。 \w 匹配任何字母数字字符; 它相当于 [a-zA-Z0-9_]。 \W 匹配任何非字母数字字符; 它相当于 [^a-zA-Z0-9_] \b 匹配一个特殊字符边界,比如空格 ,&,#等
\b 规则需要加‘r‘
执行时是python解释器执行,调用re模块实现,执行这段代码,是解释器翻译后,交给re模块的findall处理;
解释器碰到\b是有意义的(\b在ascill码中代表响铃),所以在这就要先转义,然后就把 \b 交给 re模块;
或者加 r 表示原生字符串,表示字符串内的字符都是普通字符;
print(re.findall(r"o\b","hello shuai ge")) # [‘o‘]
通过上面,理解下面
print(re.findall(r"o\\s","hello\shuai")) # [‘o\\s‘] print(re.findall("o\\\\s","hello\shuai")) # [‘o\\s‘]
() 分组
把一些内容作为一项
findall用了分组后,会把分组内容取出来(使用 ?: 取消findall功能,把匹配成功内容全部取出来)
比如匹配规则很多,想要的只是其中的几个,就可以利用分组
print(re.findall(‘(shuai)+‘,‘shuaiaashuaishuaikkl‘)) # [‘shuai‘, ‘shuai‘]
命名分组
使用?P<>来为分组命名
res = re.search(r" birthday:(?P<year>20[01]\d).(?P<month>\d+)"," birthday:2017:12") print(res.group()) # birthday:2017:12 print(res.group("year")) # 2017 print(res.group("month")) # 12
[ ] 字符集
匹配其中一个字符
字符集的元字符没有特殊意义(除:- \ ^)
res = re.findall(r"a[b*cd]","abf*cgdada*h") print(res) # [‘ab‘, ‘ad‘, ‘a*‘] # - 表示范围 res = re.findall(r"a[a-zA-Z0-9_]","ad5aQs5f4aTa5r8a_6") print(res) # [‘ad‘, ‘aQ‘, ‘aT‘, ‘a5‘, ‘a_‘] # \ 仍然转义 res = re.findall(r"a[\d]","ad5aQs5f4aTa5r8a_6") print(res) # [‘a5‘] # ^ 表示非 res = re.findall(r"a[^\d]","ad5aQs5f4aTa5r8a_6") print(res) # [‘ad‘, ‘aQ‘, ‘aT‘, ‘a_‘]
| 管道符
res = re.findall("www.\w+.(?:com|cn)","www.baidu.com,www.cf.cn") print(res) # [‘www.baidu.com‘, ‘www.cf.cn‘]
贪婪匹配:
满足匹配时,匹配尽可能短的字符串,使用?来表示非贪婪匹配
res = re.findall("123+","12333456789") print(res) # [‘12333‘]
非贪婪匹配:
满足匹配时,匹配尽可能短的字符串,使用?来表示非贪婪匹配
res = re.findall("123+?","12333456789") print(res) # [‘123‘]
常用贪婪匹配
# *? 重复任意次,但尽可能少重复 # +? 重复1次或更多次,但尽可能少重复 # ?? 重复0次或1次,但尽可能少重复 # {n,m}? 重复n到m次,但尽可能少重复 # {n,}? 重复n次以上,但尽可能少重复 # # . 是任意字符 # * 是取 0 至 无限长度 # ? 是非贪婪模式。 # 何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在: # .*?x # # 就是取前面任意长度的字符,直到一个x出现
利用正则匹配爬虫
import requests,re def getPage(): respnse_str = requests.get("https://movie.douban.com/top250?start=0&filter=") return respnse_str.text def run(): resonse = getPage() obj = re.compile(‘<div class="item">.*?<em.*?>(?P<id>\d+)</em>.*?<span class="title">(.*?)</span>‘ ‘.*?<span class="rating_num".*?>(.*?)</span>‘, re.S) ret = obj.findall(resonse) print(ret) run()
以上是关于二十正则表达式(re模块)的主要内容,如果未能解决你的问题,请参考以下文章