由于\加字符有很多的特殊含义,比如\n是换行符,我们不想让它换行可以用以下两种方法取消转义
*单独写正则表达式的时候在转义字符前加 r 一般不识别,在python中推荐使用加 r 的方法,单独写正则推荐使用双*
上篇介绍了正则表达式,在python中想要使用正则表达式,一般和内置模块re一块使用,下面介绍以下re模块的基本使用方法
re模块常用的方法
findall():根据正则匹配所有符合条件的数据,匹配成功返回list,如果没有匹配到返回空列表。
search():根据正则匹配到一个符合条件的就结束,查看结果需要用group()方法,如果没有符合条件的数据,那么返回None,没有符合条件的数据再使用group()会报错。
match():根据正则从头开始匹配,相当于正则表达式中的^,文本内容必须在开头匹配上,如果没有符合条件的数据,那么match返回None,并且使用group会直接报错
split():根据匹配的字符串进行分割
sub():替换正则匹配到的内容,如果不写替换的个数默认替换所有,返回替换之后的字符串
subn():和sub方法功能一样,结果返回元组,并提示换了几处
compile():在需要匹配相同正则表达式情况下, 事先定义一个compile可以简化代码量,可以多次多次调用compile()返回的结果
finditer():和findall方法一样,返回的结果是一个iterator,需要遍历输出
定义:findall根据正则匹配所有符合条件的数据,匹配成功返回list,如果没有匹配到返回空列表。
格式:findall(pattern, string, flags=0)
示例如下:
import re # findall示例: # 有匹配结果 res = re.findall('a.','abcaaa,ccc,abcd123') print(res) # 无匹配结果 res1 = re.findall('z','abc,123,df,eg,edg,456qqq') print(res1) # 结果 ['ab', 'aa', 'a,', 'ab'] []
定义:search根据正则匹配到一个符合条件的就结束,查看结果需要用group()方法,如果没有符合条件的数据,那么返回None,没有符合条件的数据再使用group()会报错。
格式:search(pattern, string, flags=0)
示例如下:
import re # search示例: # 有匹配结果 res = re.search('a','Hammer,Alien,Tony') print(res) # 返回match对象<_sre.SRE_Match object; span=(1, 2), match='a'> print(res.group()) # 匹配到一个就结束,Hammer中的a # 无匹配结果 res1 = re.search('b','Hammer,Alien,Tony') print(res1) # 返回None print(res1.group()) # 报错 # 结果 <_sre.SRE_Match object; span=(1, 2), match='a'> a None AttributeError: 'NoneType' object has no attribute 'group'
定义:match根据正则从头开始匹配,相当于正则表达式中的^,文本内容必须在开头匹配上,如果没有符合条件的数据,那么match返回None,并且使用group会直接报错
格式:match(pattern, string, flags=0)
示例如下:
import re # match示例: # 有匹配结果 res = re.match('a','abc,bcd,efg') print(res) print(res.group()) # 无匹配结果 res1 = re.match('b','zxc,vbn,nmk') print(res1) print(res1.group()) # 没有匹配结果使用group报错 # 结果 <_sre.SRE_Match object; span=(0, 1), match='a'> a None
示例如下:
import re # split示例: # 有匹配结果 res = re.split('ab','ab,abc,abcd') # 会根据待匹配字符中的ab切分成不同的空字符串 print(res) # 无匹配结果:原样返回,组织成列表 res1 = re.split('zq','ab,abc,abcd') # 会根据待匹配字符中的ab切分成不同的空字符串 print(res1) # 结果 ['', ',', 'c,', 'cd'] ['ab,abc,abcd']
定义:替换正则匹配到的内容,如果不写替换的个数默认替换所有,返回替换之后的字符串
格式:sub(pattern, repl, string, count=0, flags=0)
示例如下:
import re # sub示例: # 有匹配结果 res = re.sub('\d','Ze','HammerZe9854') # 将数字替换成Ze print(res) # 更改替换个数 two_change = re.sub('\d','Ze','HammerZe9854',2) # 替换两个数字 print(two_change) # 无匹配结果 res1 = re.sub('\d','Ze','HammerZe') # 将数字替换成Ze print(res1) # 没有可匹配的数字,原样输出 # 结果 HammerZeZeZeZeZe HammerZeZeZe54 HammerZe
示例如下:
import re # subn示例: # 有匹配结果 res = re.subn('\d','Ze','HammerZe9854') # 将数字替换成Ze print(res) # 更改替换个数 two_change = re.subn('\d','Ze','HammerZe9854',2) # 替换两个数字 print(two_change) # 无匹配结果 res1 = re.subn('\d','Ze','HammerZe') # 将数字替换成Ze print(res1) # 没有可匹配的数字,原样输出 # 结果 ('HammerZeZeZeZeZe', 4) ('HammerZeZeZe54', 2) ('HammerZe', 0)
定义:在需要匹配相同正则表达式情况下, 事先定义一个compile可以简化代码量,可以多次多次调用compile()返回的结果
格式:compile(pattern, flags=0)
示例如下:
# compile示例 re_exp = re.compile('\d*') # 编写公用正则公式 res = re.match(re_exp, '1aa,2bb,3cc') # 返回开头数字 print(res.group()) res1 = re.findall(re_exp, '1aa,2bb,3cc') print(res1) res2 = re.search(re_exp, '1aa,2bb,3cc') # 遇到一个符合的就结束 print(res2.group()) # 结果 1 ['1', '', '', '', '2', '', '', '', '3', '', '', ''] 1
定义:和findall方法一样,返回的结果是一个iterator,需要遍历输出
格式:finditer(pattern, string, flags=0)
示例如下:
import re res = re.finditer('\d+','HammerZe123,HammerZe456,HammerZE789') print([i.group() for i in res]) res1 = re.findall('\d+','HammerZe123,HammerZe456,HammerZE789') print(res1) # 结果,一毛一样,前者会节省资源,遍历才能输出 ['123', '456', '789'] ['123', '456', '789']
刚才描述的案例基本没有分组,下面的内容介绍分组后,通过正则匹配是有先后展示顺序的,分组可以通过小括号分组!
示例如下:
import re # 匹配身份证号的案例 # findall针对分组优先展示 无名分组 res = re.findall("^[1-9]\d{14}(\d{2}[0-9x])?$",'110105199812067023') print(res) # ['023'] # 取消分组优先展示 无名分组 res1 = re.findall("^[1-9](?:\d{14})(?:\d{2}[0-9x])?$",'110105199812067023') print(res1) # 结果 ['023'] ['110105199812067023']
示例如下:
import re # 匹配身份证号的案例 # 有名分组 res = re.search('^[1-9](?P<name1>\d{14})(?P<name2>\d{2}[0-9x])?$','110105199812067023') print(res) print(res.group()) # 110105199812067023 print(res.group(1)) # 10105199812067 无名分组的取值方式(索引取) print(res.group('name1')) print(res.group('name2')) # 结果 <_sre.SRE_Match object; span=(0, 18), match='110105199812067023'> 110105199812067023 10105199812067 10105199812067 023
import re import pandas as pd import requests url = 'http://www.redbull.com.cn/about/branch' response = requests.get(url) # print(response) <Response [200]> # 分公司名称,页面源码<h2>红牛杭州分公司</h2> get_company_name = re.findall('<h2>(.*?)</h2>', response.text) # 地址:<p class='mapIco'>杭州市上城区庆春路29号远洋大厦11楼A座</p> get_company_addre = re.findall("<p class='mapIco'>(.*?)</p>", response.text) # 邮编:<p class='mailIco'>310009</p> get_company_post = re.findall("<p class='mailIco'>(.*?)</p>", response.text) # 电话:<p class='telIco'>020-38927681</p> get_company_telephone = re.findall("<p class='telIco'>(.*?)</p>", response.text) # 调整爬取的信息结构 company_info = pd.DataFrame({'公司名': get_company_name, '地址': get_company_addre, '邮编': get_company_post, '电话': get_company_telephone}) # 存到excel表里 company_info.to_excel(excel_writer=r"db\redbull_info.xlsx", index=None) # 查看部分公司信息 line = company_info.head(10) print(line) # 结果查看elcel表格
在python中与时间相关的模块主要有time模块和datatime模块,下面分别介绍一下这两个模块
时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量
世界标准时间:全球24个时区,中国所在为东八区,UTC+8,夏令时DST。