python爬虫之正则表达式(二)

python爬虫之正则表达式(二)


在《python爬虫之正则表达式(一)》文章中,我们介绍了正则表达式的应用场景以及普通字符、元字符、预定义匹配字符集和重复匹配。在本篇博文中,我们将续上文,re模块常用方法、分组功能,以及最后进行一些练习。

1 re模块常用方法

在这里插入图片描述
在这里插入图片描述

  • compile(pattern, flags=0)
    (1)这个方法是 re 模块的工厂法,用于将字符串形式的正则表达式编译为 Pattern 模式对象,可以实现更加效率的匹配,第⼆个参数 flag 是匹配模式。
    (2)使用 compile()完成⼀次转换后,再次使用该匹配模式的时候就不能进行转换了。经过compile() 转换的正则表达式对象也能使⽤普通的 re 方法。
import  re
# compile:正则表达式的模式   re.compile(pattern='',flags='')
ptn = re.compile(r'abc')
print(ptn.match('abc123').group()) # abc
ptn = re.compile(r'abc',re.I)  #  不区分大小写
print(ptn.match('ABC123').group()) # ABC
  • search(pattern, string, flags=0)
    (1)在文本内查找,返回第⼀个匹配到的字符串。它的返回值类型和使用方法与match() 是⼀样的。
    (2)唯⼀的区别就是查找的位置不用固定在文本的开头
# search:类似于match,从任意位置查找 re.search(pattern='',string='',flags='')
print(re.search(r'abc','123abc567abc789').group()) # abc

# match: re.match(pattern='',string='',flags='')
print(re.match(r'abc','abc567abc789').group()) # abc
  • findall(pattern, string, flags=0
    (1)作为 re 模块的三大搜索函数之⼀, findall() 和 match() 、 search() 的不同之处在于,前两者都是单值匹配,找到⼀个就忽略后⾯,直接返回不再查找了。而findall 是全文查找,它的返回值是⼀个匹配到的字符串的列表
    (2)这个列表没有group() 方法,没有 start 、 end 、 span ,更不是⼀个匹配对象,仅仅是个列表!
    如果⼀项都没有匹配到那么返回⼀个空列表
# findall: re.findall(pattern=,string=,flags=) 以列表形式返回
print(re.findall(r'\d+','8+7*5+6/3')) # ['8', '7', '5', '6', '3']
print(re.findall(r'ABC','123abc567abc789',re.I)) # ['abc', 'abc']

(2)无分组

'''
无分组:匹配所有合规则的字符串,匹配到的字符串放到一个列表中
注意:正则匹配到空字符的情况,如果规则里只有一个组,而组后面是*就表示组里的内容可以是0个或者多个
这样组里就有了两个意思,一个意思是匹配组里的内容,二个意思是匹配组里0内容(即是空白)所以尽量避免用*否则会有可能匹配出空字符串
否则就会出现例子2
'''
import re
#无分组 例子1
#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
#无分组
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("a\w+", origin)    #浏览全部字符串,匹配所有合规则的字符串,匹配到的字符串放到一个列表中
print(r)
#输出结果
#['alex', 'alex', 'alex', 'acd'] #匹配所有合规则的字符串,匹配到的字符串放到一个列表中表

#无分组 例子2
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)*", origin)
print(r)
#输出结果 ['', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', 'a', '', '', '', '', '', '']

(3)有分组

'''
有分组:只将匹配到的字符串里,组的部分放到列表里返回,相当于groups()方法
'''
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("a(\w+)", origin)    #有分组:只将匹配到的字符串里,组的部分放到列表里返回
print(r)
#输出结果 #['lex', 'lex', 'lex', 'cd']

(4)多个分组

'''
多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返
相当于在group()结果里再将组的部分,分别,拿出来放入一个元组,最后将所有元组放入一个列表返回
'''
import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)(\w+)", origin)    #多个分组:只将匹配到的字符串里,组的部分放到一个元组中,最后将所有元组放到一个列表里返回
print(r)
#输出结果
#[('a', 'lex'), ('a', 'lex'), ('a', 'lex'), ('a', 'cd')]

(5)分组中有分组

'''
分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,
将包含有组的组,看作一个整体也就是一个组,放入一个元组里
然后再把组里的组放入一个元组,最后将所有组放入一个列表返回
'''

import re
origin = "hello alex bcd alex lge alex acd 19"
r = re.findall("(a)(\w+(e))", origin)    #分组中有分组:只将匹配到的字符串里,组的部分放到一个元组中,先将包含有组的组,看作一个整体也就是一个组,把这个整体组放入一个元组里,然后在把组里的组放入一个元组,最后将所有组放入一个列表返回
print(r)
#输出结果
#[('a', 'le', 'e'), ('a', 'le', 'e'), ('a', 'le', 'e')]

(6)?:

'''
?: :在有分组的情况下findall()函数,不只拿分组里的字符串,拿所有匹配到的字符串
注意?:  :只用于不是返回正则对象的函数如findall()
'''

import re
origin = "hello alex bcd alex lge alex acd 19"
b = re.findall("a(?:\w+)",origin) #?:在有分组的情况下,不只拿分组里的字符串,拿所有匹配到的字符串
# 注意?:只用于不是返回正则对象的函数如findall() 返回的是列表
print(b)
#输出
# ['alex', 'alex', 'alex', 'acd']

注意:(3)-(5)参考博文re模块中常用功能函数。这篇博文写得很详细,推荐学习

  • split(pattern, string, maxsplit=0, flags=0)
    (1)re 模块的 split() 方法和字符串的 split() 方法很相似,都是利用特定的字符去分割字符串。但是 re 模块的 split() 可以使用正则表达式,因此更灵活,更强大。
    (2)split 有个参数 maxsplit ,用于指定分割的次数
# spilt: 分割 re.split(pattern='',string='',maxsplit=,flags=) pattern是按照什么分割,string是分割的内容,max是分割最多次数,flag是分割模式
print(re.split(r'[+*\-\/]','5+3*2/1')) # ['5', '3', '2', '1']
print(re.split(r'[+*\-\/]','5+3*2/1',maxsplit=2)) # ['5', '3', '2/1']

  • sub(pattern, repl, string, count=0, flags=0)
    sub()方法类似字符串的 replace() 方法,用指定的内容替换匹配到的字符,可以指定替换次数
# sub:  re.sub(pattern=,repl=,string=,count=0,flags=)
print(re.sub('abc','124','abcEDabc',count=1,flags=re.I)) # 124EDabc
print(re.sub('abc','124','abcEDabcabc',count=0,flags=re.I)) # 124ED124124  全部替换
print(re.sub('abc','124','abcEDabcABC',count=0,flags=re.I)) # 124ED124124  全部替换 不区分大小写

2 分组功能

Python 的 re 模块有⼀个分组功能。

  • 所谓的分组就是去已经匹配到的内容再筛选出需要的内容,相当于二次过滤。==实现分组靠圆括号 () ==。
  • 而获取分组的内容靠的是 group() 、 groups() ,其实前面我们已经展示过。
# 分组
import re
# 需求是匹配到 $88  $55
text = 'apple price is $88,orange price is $55'
r = re.search('.(\d+).+(\$\d+)',text)
print(r.group(0))  # apple price is $88,orange price is $55
print(r.groups())  # ('$88', '$55')
print(r.group(1)) # $88
print(r.group(2)) # $55
result = r.groups()
print(type(result))  # <class 'tuple'>

# 需求匹配到数字
text = 'abc123cde456'
r = re.search('[a-z]+([0-9]+)[a-z]+([0-9]+)',text)
print(r.group(0))  # apple price is $88,orange price is $55
print(r.groups())  # ('123', '456')
print(r.group(1)) # 123
print(r.group(2)) # 456
result = r.groups()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值