分析:第一个<html>跟最后一个</html>是一对,内容是一样的只是后面多了一个/,同理中间也是如此,这个时候可以使用分组的思想
先使用不分组的思想匹配:
res = r"<.+><.+><.+>.+</.+></.+></.+>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
可以匹配到,然后使用分组思想,很简单,就是将<>里面的内容用()包起来,然后后面使用索引:
>>> res = r"<(.+)><(.+)><(.+)>.+</\3></\2></\1>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
分析:第一个(.+)是分组的第一个索引,匹配到的内容是html,你希望最后一个<>内也是这个值,那么就在最后的位置,写\1表示匹配第一个分组的内容
有时分组内容太多,用索引会有可能乱掉,就可以使用起别名的方式,如下:
>>> res = r"<(?P<key1>.+)><(?P<key2>.+)><(?P<key3>.+)>.+</(?P=key3)></(?P=key2)></(?P=key1)>"
>>> re.match(res,s)
<_sre.SRE_Match object; span=(0, 39), match='<html><body><p>python</p></body></html>'>
原本第一个分组里面的内容是<(.+)>,想要起别名,就在.+的前面加上?P<key1>,后面引用这个别名的时候:(?P=key1),要注意括号必须有,有括号才表示分组
如果想获取<p></p>中间的内容,应该如何获取呢,或者你想要获取每一个分组的内容?
这时候可以使用group方法,接上面的:
>>> gr = re.match(res,s)
>>> gr.group() #不写索引值就默认把匹配到的所有值都打出来
'<html><body><p>python</p></body></html>'
>>> gr.group(1) #获取第一个分组
'html'
>>> gr.group(2) #获取第2个分组
'body'
>>> gr.group(3) # 获取第3个分组
'p'
>>> gr.group(4) #获取第4个分组报错了,因为没有第4个了
Traceback (most recent call last):
File "<input>", line 1, in <module>
IndexError: no such group
如果只想获取<p></p>中间的内容python,那你要把中间匹配到的内容用()括起来,表示也是一个分组:
>>> res = r"<(?P<key1>.+)><(?P<key2>.+)><(?P<key3>.+)>(.+)</(?P=key3)></(?P=key2)></(?P=key1)>"
>>> gr = re.match(res,s)
>>> gr.group(4)
'python'
第五部分,re模块的其他方法:
Search方法,从待匹配的字符串中检索出需要的,比如从”阅读次数为 999”字符串中检索出阅读次数:
>>> ret = re.search(r"\d+","阅读次数为:999")
>>> ret.group()
'999'
Search方法只能匹配到第1次的内容,比如:
>>> ret = re.search(r"\d+","阅读次数为:999,浏览次数为:2000")
>>> ret.group()
'999'
如果想要把所有的数字都找出来,可以使用findall方法,findall方法返回的是一个列表,没有group方法,可以直接打印列表
>>>ret = re.findall(r"\d+","阅读次数为:999,浏览次数为:2000")
>>> ret
['999', '2000']
Sub方法可以替换匹配到的字符串
>>> ret = re.sub(r"\d+","1000","阅读次数为:999 ")
>>> ret
'阅读次数为:1000 '
sub方法的第一个参数是正则表达式,第2个参数为替换后的数据,第三个参数是待匹配的字符串
第二个参数也可以为一个方法名,比如将阅读次数加1:
# 定义一个方法,有一个参数,接收匹配到的数据,并且返回一个数据