正则表达式(三)— 高级用法:search,findall

进阶部分在这里:正则表达式(二)——进阶之匹配分组

4. search用法

上面我们学习了re模块的match用法,下面我们来学习下re模块中search用法!(其实也算不上高级用法啦)

match和search对比:

match的一个特点就是从左向右完整的去匹配,多出来的不管,少了就不行;

search是在给定字符串当中去搜索的符合正则表达式的内容。

match和search的语法都一样,都为re.xxxx(正则表达式,字符串)

 需求:在一段文字中,比如 "'文章篇幅为1314521个字" ,我们如何查找得到数字digit部分?

分析:关于数字的描述可以表达为 r'\d+'。

>>> result = re.search(r'\d+','文章篇幅为1314521个字')
>>> result.group()
'1314521'

这样不就把数字部分提取出来了么。你可以定义自己的正则表达式,提取想要的内容。

======================================================================================

前面在正则表达式(一)——基础之匹配字符,数量,边界中的《边界》部分,我说过一句话:^(匹配字符串开头)这个效果在match中不是很明显,原因match就是从左到右开始匹配的,它做的是匹配工作。

但是在search里,^ 效果却是十分明显的,比如当我们想要匹配以数字开头的,正则表达式为:

r'^\d+'
>>> result = re.search(r'^\d+','文章篇幅为1314521个字')
None

这样的结果是None,未能匹配。

  • Question one?

search和match都是一次性匹配,即只要匹配到内容就立马结束,看如下代码:

>>> result = re.search(r'\d+','文章篇幅为1314521个字,共234页')
>>> result.group()
'1314521'

按正常理来说,应该返回给我'1314521'和'234'啊,这就是search的一次性匹配。那有没有全部匹配的用法呢?答案:of course。就是下面的findall用法

5. findall用法

需求:在一段文字中,比如 "'文章篇幅为1314521个字,共234页,有1000张图" ,找到所有数字digit部分

分析:查找数字的正则表达式为r'\d+'

>>> result = re.findall(r'\d+','文章篇幅为1314521个字,共234页,有1000张图')
>>> result
['1314521', '234', '1000']

注意:findall返回的对象就是list类型的,支持list的所有操作

6. sub 将匹配到的数据进行替换(substitute不是sub减)

先看看sub函数:re.sub(pattern, repl, string, count=0, flags=0)

其中三个必选参数:pattern, repl, string

两个可选参数:count, flags

  • pattern,表示正则中的模式字符串
  • repl,就是replacement,被替换,的字符串的意思。repl可以是字符串,也可以是函数
  • string,即表示要被处理,要被替换的那个string字符串。

需求1:在班级模拟考试分数表上,需要对某个同学的数学成绩加20分,英语成绩加20分,比如该同学分数表内容为:”math=60,English=50"

分析:我们首先需要匹配到数字部分。再拿到数字的当前数值,在这基础上加上对应的值。先匹配再替换,sub函数可以同时完成这两件事。

======================================================================================

我们,先来简化下需求,展示repl是字符串的情况。直接把math=60,English=50的数值部分直接替换为80分:

>>> ret = re.sub(r'\d+','80','math=60,English=50')
>>> ret             #返回的是str类型
'math=80,English=80'

这样太弱智了,而且把English的数值也变成了80

======================================================================================

 因此,我们需要定义函数来处理这个逻辑,展示repl是函数的情况:

定义函数用交互环境不方便,我用IDE吧!

import re
'''result是先作查找操作,结束后得到的结果,与match或者search得到的result无异,实质上sub方法实现包括了search方法'''
def replace(result):  #定义替换函数,返回处理后的str
    print('the digit value is:',result.group())
    r = int(result.group()) + 20
    return str(r)    #转成str类型

r = re.sub(r'\d+',replace,'math=60,English=50')
print(r)

'''
output:
the digit value is: 60
the digit value is: 50
math=80,English=70
'''

======================================================================================

我们再来看个sub的实际需求应用:

需求2:在下面的python工程师招聘要求网页源码文本中,我们需要把标签都过滤掉,只留下文本。即去掉,<html>,</html>,<p>,</p>,<br/>,<span>,</span>等标签。

<html>
<p>##python开发工程师</p>
<p><span>+ python爬虫工程师</span></p>
<p>负责大规模文本、图像等数据的抓取、结构化信息的提取、质量识别等工作。</p>
<p>1. 开发分布式网络爬虫</p>
<p>2. 提取结构化信息</p>
<p>3. 识别结构化信息的质量</p>
<p>岗位要求:</p>
<p>1. 熟悉 Linux 开发环境,熟练使用 Shell</p>
<p>2. 熟悉 高并发、高性能分布式系统</p>
<p>3. 熟悉 HTTP协议,熟悉 HTML,JavaScript,XPath</p>
<p>4. 熟悉 网络协议</p>
<p>5. 从事 Python 开发 1年及以上</p>
<p>6. 熟练使用 Python 进行抓取及格式化信息提取</p>
<p>岗位职责:</p>
<p>1、根据实际任务,进行高校大数据业务开发,满足市场需求;</p>
<p>2、能独立完成项目开发文档的撰写工作;</p>
<p>3、能够与开发团队中其它成员有效沟通,包括其它工程师、项目经理、产品以及测试,设计出高性能、可扩展而且符合用户需求的方案;</p>
<p>4、对新技术具有较强的研究和解决问题的能力,并能够共享其成果在小组/部门内推广;</p>
<p>5、能够和小组中帮助其它工程师讨论并解决疑难问题;</p>
<p>6、按时保质保量完成产品开发任务;</p>
<p>7、热衷研究新兴技术,对产品进行持续优化。</p>
<p><br/></p>
<p>任职资格:</p>
<p>1、两年以上稳定开发经验,熟悉python语言</p>
<p>2、熟悉Linux操作,使用git进行版本控制管理,有nginx配置部署经验;</p>
<p>3、熟悉django tornado flask 任一python开发框架,懂代码调试并能持续优化;</p>
<p>4、熟悉HTTP协议,能开发符合RESTful设计思想的接口;</p>
<p>5、有mysql.mongodb.redis等常用数据库的使用经验;</p>
<p>6、优良的代码注释习惯,并能编写有条理的开发文档。</p>
<p>7、使用过运维工具,能自行编写简单的SHELL脚本</p>
<p>8、对技术精进有要求,愿意学习大数据相关知识,并付诸实践。</p>
<p><br/></p><p><br/></p><p><br/></p>
<p>+ Python研发工程师</p><p>要求:</p>
<p>1.	全职类工作2-4(包含)年开发经验</p>
<p>2.	Python基础扎实,熟悉常用的类库</p>
<p>3.	掌握Tornado、Django、Flask其中任一web框架,至少两年左右的web开发经验</p>
<p>4.	熟悉常用的工具如Redis,Memcached,Mongodb,Mysql,Nginx等的基本原理和使用</p><p>5.	掌握linux环境下的开发和部署,掌握gitlab的使用</p>
<p>6.	熟悉常用的数据结构、算法和设计模式等</p>
</html>

分析:首先应该分析出标签的特征,写出正则表达式。把标签内容替换为空字符串“”就可以啦。乍一看,标签是<>包括的,于是得出正则表达式:

r'<.+>'
>>> s = '''把上面内容copy下来,太多啦,占屏幕'''
>>> re.sub(r'<.+>','',s)       #结果是空的,哈哈(贪婪模式)
''

'''再看看下面的运行结果,就多了个?(非贪婪模式)'''
>>> re.sub(r'<.+?>','',s)       #就能得到正确结果
'##python开发工程师+ python爬虫工程师负责大规模文本、图像等数据的抓取、结构化信息的提取、质量识别等工作。1. 开发分布式网络爬虫2. 提取结构化信息3. 识别结构化信息的质量岗位要求:1. 熟悉 Linux 开发环境,熟练使用 Shell2. 熟悉 高并发、高性能分布式系统3. 熟悉 HTTP协议,熟悉 HTML,JavaScript,XPath4. 熟悉 网络协议5. 从事 Python 开发 1年及以上6. 熟练使用 Python 进行抓取及格式化信息提取+ python开发带薪年假,五险一金,年终奖金,调薪机制职位描述:python脚本语言熟练掌握(基础语法)了解机器学习Tensorflow使用过Django,能使用Django搭建后台服务,数据分析,分析算法方向如聚类算法加分项:会其他语言如JAVA,js,Sql了解至少一种前端MVVM框架如Angular,vue,react+ 北京特微特科技发展有限公司招聘高级中级后端开发Python运维六险一金 团建 每年调薪机会 不定期培职位描述:岗位职责:1、根据实际任务,进行高校大数据业务开发,满足市场需求;....

其实这里的原因就是,正则表达式默认是贪婪模式(这个我们将在下一节讲解),在量词后面直接加上一个问号?就是非贪婪模式。 

======================================================================================

除了这种非贪婪模式,还有其他方法么?

分析:那么我们换个角度去思考,标签都是字母,这不可否认吧,我们可以从这里出发。那么我们可以用正则r'<\w'>表示,但是像标签</html>,</p>是无法匹配的,那么对于标签<html>,/ 是可有可无的,用?表示,因此正则 r'/?\w' 表示,但是对于<br/>又是不匹配的,在字母后面的 / 也是可有可无的,因此,正则表达式为:

r'</?\w/?>'
>>> re.sub(r'</?\w/?>','',s)
'##python开发工程师+ python爬虫工程师负责大规模文本、图像等数据的抓取、结构化信息的提取、质量识别等工作。1. 开发分布式网络爬虫2. 提取结构化信息3. 识别结构化信息的质量岗位要求:1. 熟悉 Linux 开发环境,熟练使用 Shell2. 熟悉 高并发、高性能分布式系统3. 熟悉 HTTP协议,熟悉 HTML,JavaScript,XPath4. 熟悉 网络协议5. 从事 Python 开发 1年及以上6. 熟练使用 Python 进行抓取及格式化信息提取<br />+ python开发带薪年假,五险一金,年终奖金,调薪机制<br />职位描述:python脚本语言熟练掌握(基础语法)了解机器学习Tensorflow使用过Django,能使用Django搭建后台服务,数据分析,分析算法方向如聚类算法<br />加分项:会其他语言如JAVA,js,Sql了解至少一种前端MVVM框架如Angular,vue,react<br /><br />+ 北京特微特科技发展有限公司招聘高级中级后端开发Python运维六险一金 团建 每年调薪机会 不定期培<br />职位描述:岗位职责:1、根据实际任务,进行高校大数据业务开发,满足市场需求;

同样达到了效果......

7. spilt 根据匹配进行切割字符串,并返回列表

猜你喜欢

转载自blog.csdn.net/m0_37673307/article/details/81627553