正则表达式
正则表达式
什么是正则表达式
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
re模块在Python中提供对Perl类正则表达式的完全支持。re 模块使 Python 语言拥有全部的正则表达式功能。如果在编译或使用正则表达式时发生错误,则re模块会引发异常re.error。
正则表达式
正则表达式测试网站
在线测试网站:http://tool.chinaz.com/regex/
字符组
'''单个字符组默认一次只匹配一个字符'''
[0123456789] 匹配0到9之间的任意一个数字
[0-9] 匹配0到9之间的任意一个数字(简写)
[a-z] 匹配a到z之间的任意一个小写字母
[A-Z] 匹配A到Z之间的任意一个大写字母
[0-9a-zA-Z] 匹配任意一个数字或者大小写字母(没有顺序)
常用特殊符号
'''前期就是死记硬背 使用频率高了之后自然就记住了'''
# 特殊符号默认也是一次匹配一个字符
. 匹配除换行符(\n)以外的任意字符
\w 匹配数字、字母、下划线(后续筛选变量名可能用到)
\d 匹配任意的数字
\t 匹配一个制表符(tab键)
^ 匹配字符串的开始
eg:^9 找9并且这个9必须在开头
$ 匹配字符串的结尾
eg:9$ 找9并且这个9必须在末尾
\W 匹配非字母或数字或下划线
\D 匹配非数字
a|b 匹配a或者b 管道符就是or(或)的意思
() 给正则表达式分组 不影响正则匹配(后续再讲)
[] 字符组的概念(里面所有的数据都是或的关系)
[^] 上箭号出现在了中括号的里面意思是取反操作
量词
"""量词必须跟在表达式的后面 不能单独使用 目的是增加匹配的字符数"""
* 匹配0次或多次(默认是多次)
+ 匹配1此或多次(默认是多次)
? 匹配0次或1次(默认是一次)
{n} 匹配n次
{n,} 匹配最少n次最多多次(默认多次)
{n,m} 匹配最少n次最多m次(默认m次)
取消转义
我们使用'\'来进行转义,对需要转义的如'\n',前再加一个'\'就可以实现转义。
\\n \n
\\\\n \\n
在python中还可以在字符串的前面加r取消转义 更加方便
贪婪匹配和非贪婪匹配
假设我们要进行匹配的字符串是<python> perl>
贪婪匹配 | 示例:<.*> | 匹配'<python> perl>' |
---|---|---|
非贪婪匹配 | 示例:<.*?> | 在“<python> perl”中匹配“<python>” |
量词默认都是贪婪匹配 如果想修改为非贪婪匹配 只需要在量词的后面加?即可
re模块
了解re模块
正则表达式(Regular Expression)是字符串处理的常用工具,通常被用来检索、替换那些符合某个模式
(Pattern)的文本。很多程序设计语言都支持正则表达式,像Perl、Java、C/C++。在 Python 中是通过
标准库中的re 模块 提供对正则的支持。
通过使用正则表达式,可以:
测试字符串内的模式。—— 例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
替换文本。—— 可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
基于模式匹配从字符串中提取子字符串。—— 可以查找文档内或输入域内特定的文本。
# 在python中无法直接使用正则 需要借助于模块
1.内置的re模块
2.第三方的其他模块
方法
1.findall
re.findall(正则表达式,待匹配的文本)
结果是所有符合条件的数据 并且组织成了列表
语法:re.match(pattern, string, flags=0)
'''
pattern 匹配的正则表达式
string 要匹配的字符串
flags
标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.I 忽略大小写
re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
re.M 多行模式
re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
re.X 为了增加可读性,忽略空格和 # 后面的注释
'''
2.finditer
返回一个可迭代对象
对可迭代对象进行迭代,每一次返回一个匹配对象,可以调用匹配对象的group()方法查看指定组匹配
到的内容,0表示整个正则表达式匹配到的内容
res = re.finditer('2', '111122223333') # finditer(正则表达式,待匹配的文本)
print(res) # 结果是一个迭代器对象 为了节省空间
print([obj.group() for obj in res]) # ['2', '2', '2', '2']
3.search
re.search(正则表达式,待匹配的文本)
res = re.search('2', '111122223333') # search(正则表达式,待匹配的文本)
print(res) # 查找到一个符合条件的数据就结束 没有则返回None
print(res.group()) # 2 没有则无法调用group() 直接报错
4.match
re.match(正则表达式,待匹配的文本)
res = re.match('2', '111122223333') # match(正则表达式,待匹配的文本)
print(res) # None 从字符串的开头匹配 如果没有则直接返回None 类似于给正则自动加了^ 如果符合也只获取一个就结束
print(res.group()) # j 没有则无法调用group() 直接报错
5.comilpe
提前先写好我们需要经常使用到的正则表达式,方便后面使用时不需要再重新写一遍
com = re.compile('\d+')
print(re.findall(com, '123zxc321asd')) # ['123', '321']
print(re.findall(com, '2343wesad5asd223dsxada2')) # ['2343', '5', '223', '2']
正则表达式特殊符号和量词(表格)
编号 | 表达式 | 描述 |
---|---|---|
1 | \d | 代表任意数字,就是阿拉伯数字0-9这些玩意。 |
2 | \D | 大写的就是和小写的唱反调,\d你代表的是任意数字是吧?那么我 \D就代表不是数字的。 |
3 | \w | 代表字母,数字,下划线。也就是a-z、A-Z、0-9、-。 |
4 | \W | 跟\w唱反调,代表不是字母,不是数字,不是下划线的。 |
5 | \n | 代表一个换行 |
6 | \r | 代表一个回车 |
7 | \f | 代表换页 |
8 | \t | 代表一个Tab |
9 | \s | 代表所有的空白字符,也就是上面这个:\n、\r、\t、\f。 |
10 | \S | 跟\s唱反调,代表所有不是空白的字符。 |
11 | \A | 代表字符串的开始 |
12 | \Z | 代表字符串的结束 |
13 | ^ | 匹配字符串开始的位置 |
14 | $ | 匹配字符串结束的位置 |
15 | a,x,9,< | 普通字符完全匹配 |
16 | . | 匹配任何单个字符,除了换行符'\n' |
17 | [] | 代表在[]范围内的字符,比如[a-z]就代表a到z的字母,还有[0-9] |
18 | [^...] | 跟[...]唱反调,代表不在范围内的字符 |
19 | 匹配前面的表达式n次,比如: o{2}不能匹配 Bob中的o,但是能匹配food中的两个o。 | |
20 | 匹配前面的表达式至少n次,最多m次。匹配在{n,m}前面的东西,比如:o{1,3}将匹配“fooooood"中的前三个o。 | |
21 | 匹配前面表达式至少n次。匹配在{n,}前面的东西,比如:o{2,}不能匹配"Bob"中的"o",但能匹配“foooood"中的所有o。 | |
22 | 匹配前面的表达式最多n次 | |
23 | * | 匹配前面的字符0次或多次和{0,}一个样,匹配前面的О次或多次。比如zo能匹配"z”、“zo"以及"zoo"。 |
24 | + | 匹配前面的字符1次或者多次,和{1,}一个样,匹配+前面1次或多次。比如zo+"能匹配"zo"以及“zoo",但不能匹配“z”。 |
25 | ? | 匹配前面的字符0次或1次,和{0,1}一个样,匹配?前面0次或1次。 |
26 | a|b | 匹配a或者b |
27 | () | 匹配括号里面的内容。 |
今日作业
使用正则筛选出网站的数据http://www.redbull.com.cn/about/branch
将公司名称 地址 邮编 电话筛选出来
展示可以是格式化输出也可以是文件存储
import re
import requests
res = requests.get(url='http://www.redbull.com.cn/about/branch')
with(open('1.txt','wb')) as f:
for i in res:
f.write(i)
com = re.compile('data-describe=\'(.*?)\'><h2>(.*?)</h2><p class=\'mapIco\'>(.*?)</p><p class=\'mailIco\'>(.*?)</p><p class=\'telIco\'>(.*?)</p></li>')
with(open('1.txt', 'r', encoding='utf8')) as f2:
txt = f2.read()
res1 = com.findall(txt)
print(res1)
for i in res1:
print("""
公司名称:{}
地址:{}
邮编:{}
电话:{}
""".format(i[1],i[2],i[3],i[4]))