1. 正则表达式
正则表达式,又称规则表达式**。**(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。——百度百科
下面是正则表达式常见的使用场景:
- 检查字符串的合法性
- 验证用户名 (a-z,0-9,不能全是数字,不能全是字母)
- 验证邮箱格式 (xxx@qq.com)
- 验证电话号码 (11位数字)
- 验证身份证 (18位 )
- 验证QQ号码格式(5-12纯数字,第一位不能为0);
- 提取字符串中信息
- 提取一条短信中数字;
- 提取文件名的后缀;
- 采集器(网络爬虫)
- 替换字符串
- 替换字符串中的非法字符;
- 对电话号码进行屏蔽;(1852****0102)
- 替换占位符 “hello { {name}} ” hello 王老二 (模板框架)
- 分割字符串
- 将一个字符串按照指定的规则进行分割;
在爬虫中,使用正则表达式提取我们想要的数据。去掉多余的数据。
场景:找所有邮件地址
百度贴吧邮箱信息:http://tieba.baidu.com/p/5781191467
text = """
回复(2)4楼2018-07-04 11:48
哥哥口袋有糖
初识物联1
346504108@qq.com
收起回复5楼2018-07-04 14:10
Super劫Zed: 540775360@qq.com
2018-8-8 16:00回复
我也说一句
RAVV2017
物联硕士4
以上的邮箱,已发,还需要的请回复邮箱。两套物联网学习资料。
回复(4)7楼2018-07-04 16:06
儒雅的刘飞3
初识物联1
397872410@qq.com,谢谢楼主
收起回复8楼2018-07-04 16:20
RAVV2017: 已发送,麻烦请查收,谢谢
2018-7-4 16:23回复
我也说一句
该来的总会来
物联博士5
1459543548@qq.com
谢谢谢谢
回复9楼2018-07-04 17:18来自Android客户端
BLACKPINK_罗捷
深入物联2
1228074244@qq.com
"""
346504108@qq.com
Super劫Zed: 540775360@qq.com
397872410@qq.com,谢谢楼主
1459543548@qq.com
1.1 元字符
使用元字符匹配单个字符
字符 | 功能 |
---|---|
. | 匹配任意1个字符(除了\n) |
[ ] | 匹配[ ]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字,即不是数字 |
\s | 匹配空白,即 空格,tab键,换行 |
\S | 匹配非空白(数字、英文字符、特殊符号) |
\w | 匹配单词字符,即a-z、A-Z、0-9、_ |
\W | 匹配非单词字符 |
* | 匹配前一个字符出现0次或者无限次,即可有可无 |
+ | 匹配前一个字符出现1次或者无限次,即至少有1次 |
\d匹配数字
#coding=utf-8
import re
res = re.findall("\d",'346504108@qq.com')
print(res)
运行结果:
['3', '4', '6', '5', '0', '4', '1', '0', '8']
+ * 匹配多个字符
import re
res = re.findall("\d+",'346504108@qq.com')
print(res)
运行结果:
['346504108']
\d与[]
(字符集)
可能会出现的一些情况
[123456zxcv] 字符集只能匹配一个出现在集合里面的值
\d代表0到9的所有数字,[0123456789] 与\d等效
import re
res = re.findall("\d+",'346504108@qq.com')
print(res)
res1 = re.findall("[0123456789]+",'346504108@qq.com')
print(res1)
运行结果:
['346504108']
['346504108']
思考:邮箱可能出现为字符串,该如何处理?
例如:yanglong985@163.com
提示: [a-z]
使用点匹配任意字符
案例:匹配中国电信手机号码
- 中国电信号段
133. 153. 180. 189 - 号码总长度为11位
实现方式:
- 编写电信号码的正则
- 进行匹配
- 打印结果
import re
str_phone = """13357024777
电信 浙江省 衢州 尾数AAA 号码吉凶
18948121234
电信 广东省 茂名 尾数ABCD 号码吉凶
13873179698
移动 湖南省 长沙 个性靓号 号码吉凶
15802648889
移动 湖南省 长沙 尾数AAABAAAB号码吉凶
"""
# 第一位都是以1开头 第二位可以为34578 第三位没有6与9 后面都是数字
res = re.findall('1[358][039]\d+', str_phone)
print(res)
使用.*匹配任意多个字符
思考:匹配 Hello
与 Demo
之间的内容
import re
content = 'Hello 1234567 World_This is a Rexgex Demo'
result = re.findall('Hel.* Rexgex Demo', content)
print(result)
1.2 数量词
使用数量词匹配多个字符
字符 | 功能 |
---|---|
{m} | 匹配前一个字符出现m次 |
{m,n} | 匹配前一个字符出现从m到n次 |
需求:匹配出,8到20位的密码,可以是大小写英文字母、数字、下划线
#coding=utf-8
import re
res = re.findall("[a-zA-Z0-9]{8}","ash2e223 3424kjkljkljf 34523nmkdsjf")
print(res)
ret = re.findall("[a-zA-Z0-9_]{8,20}","ash2e223 3424kjkljkljf 34523nmkdsadsjf")
print(ret)
案例:QQ
号码匹配
QQ
号规则- 第一位数字不能为0
- 可能是 5-12 位
qq_str = """
346504108@qq.com
Super劫Zed: 540775360@qq.com
397872410@qq.com,谢谢楼主
1459543548@qq.com
"""
ret = re.findall("[1-9][0-9]{4,11}",qq_str)
print(ret)
运行结果:
['346504108', '540775360', '397872410', '1459543548']
1.3 精确匹配与泛匹配
泛匹配
泛匹配是匹配所有的东西
import re
content = 'Hello 1234567 World_This is a Rexgex Demo'
result = re.find('Hello.*Demo', content)
print(result)
精确匹配
精确匹配是匹配括号里面的东西
import re
content = 'Hello 1234567 World_This is a Rexgex Demo'
result = re.findall('Hello (\d+).*Demo', content)
print(result)
1.4 贪婪匹配与非贪婪匹配
Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。
import re
content = 'Hello 1234567 World_This is a Rexgex Demo'
result = re.findall('Hel.*(\d+)', content)
print(result)
正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。
解决方式:非贪婪操作符“?”,这个操作符可以用在"*","+","?"的后面,要求正则匹配的越少越好。
http://bulletin.sntba.com/biddingBulletin/2020-01-09/158090.html
2. re模块
一直以来我们都是使用 re.search()
函数,其实在正则表达式模块中还有一些函数可以很方便的对字符串进行操作。re
模块的使用可以分为两种:第一种是对象式的方式,第二种是函数式的方式。
re.match
match()
用于查找字符串的头部(也可以指定起始位置),它是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果。它的一般使用形式如下:
match(pattern, string[, flag])
其中,pattern
是正则表达式规则字符串,string
是待匹配的字符串,flag
是可选参数。
当匹配成功时,返回一个 Match
对象,如果没有匹配上,则返回 None
。
# 导入模块
import re
# 正则
pattern = 'Python'
# 字符串
string = 'PythonahsdgjasghPythonasdjajsk'
# 匹配
result = re.match(pattern,