您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Python

Python正则表达式详解

时间:2019-08-07 18:01:01  来源:  作者:

正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能。

正则表达式在不同的语言中使用方式不尽相同,不过只要学会了任意一门语言的正则表达式用法,其他语言中大部分也只是换了个函数的名称而已,本质都是一样的。

注:本文摘自 i 春秋社区(bbs.ichunqiu.com),欢迎更多优秀作者去社区投稿,帮助更多萌新们快速掌握新技能。文章阅读用时约10分钟。

「黑客必备技能」Python正则表达式详解

 

原子

原子是正则表达式中最基本的单位,每个正则表达式中至少要包含一个原子。常见的原子类型:

  • 普通字符作为原子
  • 非打印字符作为原子
  • 通用字符作为原子
  • 原子表

普通字符作为原子

演示代码:

import re#引用re
string = "shentouyun"#定义整段,普通字符作为原子
pat = "yun"#提取yun
ret = re.search(pat,string)#第一个参数为提取,第二个为整个字段
print(ret)#输出

输出

<_sre.SRE_Match object; span=(7, 10), match='yun'>

非打印字符作为原子

什么是非打印字符,如n,t(换行,制表),代表一些操作的字符也可以作为原子

操作代码与小知识

string1 = '''shentouyun
nuibi
'''
pat1 = 'n'
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(10, 11), match='n'>

小知识

#在这里解释一个基础,我没有提到过
string = '''
shentouyun
nuibi
'''
print(string)
#这段代码里,其特点为string被三引号包裹,并在代码里实现换行其运行结果
shentouyun
nuibi
#实现了一个n的操作其代码等同于
string ="shentouyunnnuibi"
print(string)

 

通用字符作为原子

什么是通用字符?

1. w匹配任意一个字母数字或下划线;

2. W匹配除去字母数字或下划线任意一个字符;

3. d匹配十进制数;

4. D除十进制以外的任意一个字符;

5. s匹配一个空白字符;

6. S除去空白字符。

简单的例子

string1 = "shentouyun3215454biji"
pat1 = 'dddd'#匹配四个十进制数
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(10, 14), match='3215'>

也可以混合使用

string1 = "shentouyun3215454biji"
pat1 = 'wdddd'#匹配一个字母+匹配四个十进制数
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(9, 14), match='n3215'>

没有符合格式的,如空白就不会匹配出来,这里不过多的描述,占用空间。

原子表

[ots]任意的提取一个原子出来,直接任意选择一个原子表原子,如下:

string1 = "shentouyun3215454biji"
pat1 = "shen[otoasdjojds]ou"
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(0, 7), match='shentou'>

只从原子表中选择一个原子,其原子表内原子地位平等。

非原子表

符号^ 英文状态下的shift+6

字符串里出现了非原子表,返回None,其代码如下:

string1 = "shentouyun3215454biji"
pat1 = "shen[^tun]ou"
#shen后面应该是匹配t结果原子表里出了[tun]三个原子外其他的原子都可以匹配
#显然本代码中的原子是无法匹配的
ret=re.search(pat1,string1)
print(ret)

返回如下:

None

如果正常运行非原子表外的字符如string1字符串中截取的shen后面是t,在非原子表上,没有出现t,则返回shent。

string1 = "shentouyun3215454biji"
pat1 = "shen[^asd]"
#为了更加直白我把ou两个字符去掉了
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(0, 5), match='shent'>

元字符

特殊含义的字符

所谓的元字符,就是正则表达式中具有一些特殊含义的字符,比如重复N多次前面的字符。

「黑客必备技能」Python正则表达式详解

 

 

"."除换行外任意一个字符

代码如下:

string1 = "shentouyun3215454biji"
pat1 = "shen.ou"#这里.匹配除了换行符外的任意字符
ret=re.search(pat1,string1)
print(ret)

运行结果

<_sre.SRE_Match object; span=(0, 7), match='shentou'>

当然你也可以多匹配些,比如多些点点。

string1 = "shentouyun3215454biji"
pat1 = "shen......"
ret=re.search(pat1,string1)
print(ret)

运行后

<_sre.SRE_Match object; span=(0, 10), match='shentouyun'>

开始位置^与结束位置$

string1 = "shentouyun3215454biji"
pat1 = "^s..."
ret=re.search(pat1,string1)
print(ret)
运行后
<_sre.SRE_Match object; span=(0, 4), match='shen'>

因为s是开始,也就是“排头”结束位置也同理。

string1 = "shentouyun3215454biji"
pat1 = "b...$"
ret=re.search(pat1,string1)
print(ret)
运行后
<_sre.SRE_Match object; span=(17, 21), match='biji'>

*""0次1次多次**

string1 = "shentouyun3215454biji"
pat1 = "shen.*"
ret=re.search(pat1,string1)
print(ret)
运行后
<_sre.SRE_Match object; span=(0, 21), match='shentouyun3215454biji'>

为什么会全匹配,看*号的定义为多次,咱们的"."表示除了换行外全匹配,两者一配合。

+号与?号

+匹配多次,正常显示无法匹配0次,演示错误例子。

string1 = "shentouyun3215454biji"
pat1 = "a+"
ret=re.search(pat1,string1)
print(ret)
None

演示正确例子

string1 = "aaaaaaaaaaaa"
pat1 = "a+"
ret=re.search(pat1,string1)
print(ret)
<_sre.SRE_Match object; span=(0, 12), match='aaaaaaaaaaaa'>

问号就更好弄了

问号直接演示错误例子,无法显示多次

string1 = "aaaafsedfsfdffasafadaaaaaaaa"
pat1 = "a?"
ret=re.search(pat1,string1)
print(ret)
<_sre.SRE_Match object; span=(0, 1), match='a'>

{n}与{n,}

string1 = "aaaa"
pat1 = "a{4}"
ret=re.search(pat1,string1)
print(ret)
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>

如果换成3呢

<_sre.SRE_Match object; span=(0, 3), match='aaa'>

打印了三次,成功演示了什么叫做至少,当然你多了不行,改成5试试。

None

{n,m}至少多少次,至多多少次

string1 = "aaaa"
pat1 = "a{3,5}"
ret=re.search(pat1,string1)
print(ret)
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>

模式修正符

所谓的模式修正符,即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能。

模式修正符有什么?

I忽略大小写

M多行匹配

L本地化识别匹配

U unicode编码

S让匹配包括换行符

错误代码演示

string = "ShenTouYun"
pat="shen"
ret = re.search(pat,string)
print(ret)

返回None,因为默认有大小写限制,引用一下I就可以了。

string = "ShenTouYun"
pat="shen"
ret = re.search(pat,string,re.I)
print(ret)

运行结果

<_sre.SRE_Match object; span=(0, 4), match='Shen'>

 

贪婪模式与懒惰模式

贪婪模式的核心点就是尽可能多的匹配

懒惰模式的核心就是尽可能少的匹配

贪婪模式

string = "SheSnTouYunYS"
pat="s.*S"
ret = re.search(pat,string,re.I)
print(ret)

运行结果

<_sre.SRE_Match object; span=(0, 13), match='SheSnTouYunYS'>

贪婪模式与懒惰模式有什么用呢?

看对比

string = "SheSnTouYunYS"
pat="s.*S"#贪婪模式找到最后一个s
pat1="s.*?S"#懒惰模式,特征为?,找到第一个s就不往下找了
ret = re.search(pat,string,re.I)
ret1 = re.search(pat1,string,re.I)
print(ret)
print(ret1)

运行结果

<_sre.SRE_Match object; span=(0, 13), match='SheSnTouYunYS'>
<_sre.SRE_Match object; span=(0, 4), match='SheS'>

 

正则表达式函数

1、re.match( )函数从头开始匹配

2、re.search( )函数从任何地方开始匹配

3、全局匹配函数

match函数演示

string1 = "a**fewfaaa"
pat1 = "a"
ret=re.match(pat1,string1)
print(ret)
运行结果可匹配
<_sre.SRE_Match object; span=(0, 1), match='a'>

不是第一个开始匹配

string1 = "a**fewfaaa"
pat1 = "d"
ret=re.match(pat1,string1)
print(ret)
运行结果不可匹配
None

 

全局匹配函数

全局匹配格式

re.compile(正则表达式).findall(数据)
string1 = "a**fewfaaa"
pat1 = "d.*?a"
ret=re.compile(pat1).findall(string1)
print(ret)
结果
['da']

在码文中的一些杂乱代码

import re#引用re
'''
string = "shentouyun"#定义整段,普通字符作为原子
pat = "yun"#提取yun
ret = re.search(pat,string)#第一个参数为提取,第二个为整个字段
print(ret)#输出
match
sub
search
全局匹配
string = "SheSnTouYunYS"
pat="s.*S"#贪婪模式找到最后一个s
pat1="s.*?S"#懒惰模式,特征为?,找到一个y就不往下找了
ret = re.search(pat,string,re.I)
ret1 = re.search(pat1,string,re.I)
print(ret)
print(ret1)
'''

首先预热下,爬取豆瓣首页

导入urllib库下的request

import urllib.request

使用下urlopen打开网站返回html

urllib.request.urlopen("https://www.douban.com/")

读一下看看拿到了什么东西,使用read( ),并给douban保存方便再GUI里调用

douban = urllib.request.urlopen("https://www.douban.com/").read()

可以独立尝试,会非常卡。简单点是用len看字节

>>> len(douban)
105653

 

爬取豆瓣评论

导入正则模块(re)

import re

写了个例子

#豆瓣评论爬取小例子
import urllib.request
import re
douban = urllib.request.urlopen("https://movie.douban.com/subject/27199913/?from=showing").read().decode("UTF-8")
pat = '<span class="short">.*?</span>'
rst = re.compile(pat).findall(douban)
print(rst[0])

引用decode("UTF-8")对其解码为utf-8

正则为

<span class="short">(.*?)</span>

如何写正则与本例的细节

打开网站

https://movie.douban.com/subject/27199913/?from=showing

右键源代码

发现评论格式为

<span class="short">就是山西版本的《两杆大烟枪》或者说《疯狂的石头》,将山西风光和特色与影片融合的很好,虽然还是有所瑕疵,也难逃一些俗套烂大街的剧情和段子,但是还可以。</span>

所有评论被标签包裹,可以进行抓取,使用懒惰模式进行操作。

<span class="short">.*?</span>

"."全匹配,其细节为标签里有双引号,我们再写正则时使用单引号括起来,不要再使用双引号了。

写循环把东西都显示出来

for i in range(0,len(rst)):
 print(rst[i])

运行为

>>> ================================ RESTART ================================
>>>
['一直很喜欢这种结构的电影,一圈圈地放出线团,再一段段收回,圆融又宿命。以山西籍为主的演员都挺走心的,生活的鸡飞狗走很是活灵活现,而且骆达华的出场太惊喜。导演说是改编太贵,索性自己写。但要是看过《提着心吊着胆》,会发现许多元素重合度很高,比如生意惨淡的饭店、存在问题的夫妇、警察、笨贼、拜金女、装大款……就连意外之财也是丢在饭店里。电影结尾顾虑较多,但整体完成度与幽默感不差。@平遥,特意买票支持,却来...', '算是一部跟期待打平的作品吧,中规中矩,没有惊艳,王大治倒是真有那么几分长相之外的亮点。故事一圈圈闪回,重复的部分有点多,生怕观众跟不上这个倒叙+插叙的节奏似的。四川话河南话陕西话山西话一锅烩,泱泱大中华式的热闹。想要揭示人心叵测,但终归是浅了一点。【平遥电影节2018.10.19', '这种结构挺好', '审美疲劳,这种太多了,都大同小异。从每组人物的角度,反复讲同一个事。国产电影里的歹徒劫匪都是来搞笑的,都是**,呵呵。', '巧就巧在结构上。']
一直很喜欢这种结构的电影,一圈圈地放出线团,再一段段收回,圆融又宿命。以山西籍为主的演员都挺走心的,生活的鸡飞狗走很是活灵活现,而且骆达华的出场太惊喜。导演说是改编太贵,索性自己写。但要是看过《提着心吊着胆》,会发现许多元素重合度很高,比如生意惨淡的饭店、存在问题的夫妇、警察、笨贼、拜金女、装大款……就连意外之财也是丢在饭店里。电影结尾顾虑较多,但整体完成度与幽默感不差。@平遥,特意买票支持,却来...
算是一部跟期待打平的作品吧,中规中矩,没有惊艳,王大治倒是真有那么几分长相之外的亮点。故事一圈圈闪回,重复的部分有点多,生怕观众跟不上这个倒叙+插叙的节奏似的。四川话河南话陕西话山西话一锅烩,泱泱大中华式的热闹。想要揭示人心叵测,但终归是浅了一点。【平遥电影节2018.10.19
这种结构挺好
审美疲劳,这种太多了,都大同小异。从每组人物的角度,反复讲同一个事。国产电影里的歹徒劫匪都是来搞笑的,都是**,呵呵。
巧就巧在结构上。
>>>

保存到本地

fh = open("G:\Python\doubanpinglun.txt","w")#打开文件并新建doubanpinglun.txt

open里的路径为本地路径

完整代码如下:

#豆瓣评论爬取小例子
import urllib.request
import re
douban = urllib.request.urlopen("https://movie.douban.com/subject/27199913/?from=showing").read().decode("UTF-8")
pat = '<span class="short">(.*?)</span>'
rst = re.compile(pat).findall(douban)
print(rst)
fh = open("G:\python\doubanpinglun.txt","w")#打开文件并新建doubanpinglun.txt
for i in range(0,len(rst)):
 print(rst[i])
 fh.write(rst[i]+"n")#写入文件
fh.close()#关闭文件

以上就是今天分享的内容,大家学会了吗?



Tags:Python 正则表达式   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
“代码胜于雄辩。”&mdash;&mdash;林纳斯&middot;托瓦兹(Linus Torvalds)许多编程语言和操作系统都支持正则表达式(regular expression):定义搜索模式的一组字符串。正则表达式可...【详细内容】
2020-07-14  Tags: Python 正则表达式  点击:(37)  评论:(0)  加入收藏
为什么要学正则表达式实际上爬虫一共就四个主要步骤:明确目标 (要知道你准备在哪个范围或者网站去搜索) 爬 (将所有的网站的内容全部爬下来) 取 (去掉对我们没用处的数据) 处...【详细内容】
2019-11-22  Tags: Python 正则表达式  点击:(47)  评论:(0)  加入收藏
正则表达式是一个很强大的字符串处理工具,几乎任何关于字符串的操作都可以使用正则表达式来完成,作为一个爬虫工作者,每天和字符串打交道,正则表达式更是不可或缺的技能。正则表...【详细内容】
2019-08-07  Tags: Python 正则表达式  点击:(240)  评论:(0)  加入收藏
▌简易百科推荐
大家好,我是菜鸟哥,今天跟大家一起聊一下Python4的话题! 从2020年的1月1号开始,Python官方正式的停止了对于Python2的维护。Python也正式的进入了Python3的时代。而随着时间的...【详细内容】
2021-12-28  菜鸟学python    Tags:Python4   点击:(1)  评论:(0)  加入收藏
学习Python的初衷是因为它的实践的便捷性,几乎计算机上能完成的各种操作都能在Python上找到解决途径。平时工作需要在线学习。而在线学习的复杂性经常让人抓狂。费时费力且效...【详细内容】
2021-12-28  风度翩翩的Python    Tags:Python   点击:(1)  评论:(0)  加入收藏
Python 是一个很棒的语言。它是世界上发展最快的编程语言之一。它一次又一次地证明了在开发人员职位中和跨行业的数据科学职位中的实用性。整个 Python 及其库的生态系统使...【详细内容】
2021-12-27  IT资料库    Tags:Python 库   点击:(2)  评论:(0)  加入收藏
菜单驱动程序简介菜单驱动程序是通过显示选项列表从用户那里获取输入并允许用户从选项列表中选择输入的程序。菜单驱动程序的一个简单示例是 ATM(自动取款机)。在交易的情况下...【详细内容】
2021-12-27  子冉爱python    Tags:Python   点击:(4)  评论:(0)  加入收藏
有不少同学学完Python后仍然很难将其灵活运用。我整理15个Python入门的小程序。在实践中应用Python会有事半功倍的效果。01 实现二元二次函数实现数学里的二元二次函数:f(x,...【详细内容】
2021-12-22  程序汪小成    Tags:Python入门   点击:(32)  评论:(0)  加入收藏
Verilog是由一个个module组成的,下面是其中一个module在网表中的样子,我只需要提取module名字、实例化关系。module rst_filter ( ...); 端口声明... wire定义......【详细内容】
2021-12-22  编程啊青    Tags:Verilog   点击:(9)  评论:(0)  加入收藏
运行环境 如何从 MP4 视频中提取帧 将帧变成 GIF 创建 MP4 到 GIF GUI ...【详细内容】
2021-12-22  修道猿    Tags:Python   点击:(6)  评论:(0)  加入收藏
面向对象:Object Oriented Programming,简称OOP,即面向对象程序设计。类(Class)和对象(Object)类是用来描述具有相同属性和方法对象的集合。对象是类的具体实例。比如,学生都有...【详细内容】
2021-12-22  我头秃了    Tags:python   点击:(9)  评论:(0)  加入收藏
所谓内置函数,就是Python提供的, 可以直接拿来直接用的函数,比如大家熟悉的print,range、input等,也有不是很熟,但是很重要的,如enumerate、zip、join等,Python内置的这些函数非常...【详细内容】
2021-12-21  程序员小新ds    Tags:python初   点击:(5)  评论:(0)  加入收藏
Hi,大家好。我们在接口自动化测试项目中,有时候需要一些加密。今天给大伙介绍Python实现各种 加密 ,接口加解密再也不愁。目录一、项目加解密需求分析六、Python加密库PyCrypto...【详细内容】
2021-12-21  Python可乐    Tags:Python   点击:(8)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条