Python学习之路——正则表达式练习

0. 前言

跟着老师的节奏学到了正则表达式,这一块我早有耳闻,听说很有用。但一学起来那叫一个无聊,上来就是一堆毫无规律的规则,硬着头皮听完之后课下又自学了很近才勉强掌握了点皮毛,但一做题又懵逼了。这个正则表达式太灵活了,需要多做题多训练才可以熟练掌握。个人把自己自己练习中遇到的一些题目分享于此,与君共勉。

1.去除以下html文件中的标签,只显示文本信息

这个题目上来就比较硬核,对于我来说各种查资料(copy)很久才弄清楚。以下面这个HTML文档为例

<div>
   <p>岗位职责:</p>
   <p>完成推荐算法、数据统计、接口、后台等服务器端相关工作</p>
   <p><br></p>
   <p>必备要求:</p>
   <p>良好的自我驱动力和职业素养,工作积极主动、结果导向</p>
   <p>&nbsp;<br></p>
   <p>技术要求:</p>
   <p>1、一年以上 Python 开发经验,掌握面向对象分析和设计,了解设计模式</p>
   <p>2、掌握HTTP协议,熟悉MVC、MVVM等概念以及相关WEB开发框架</p>
   <p>3、掌握关系数据库开发设计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种<br></p>
   <p>4、掌握NoSQL、MQ,熟练使用对应技术解决方案</p>
   <p>5、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js</p>
   <p>&nbsp;<br></p>
   <p>加分项:</p>
   <p>大数据,数理统计,机器学习,sklearn,高性能,大并发。</p>
</div>

最简单的一个思路就是用替换的思想,把这些标签替换为空字符串,pattern也很好写,只需要匹配<>中的数据即可,代码如下:

import re

p = r'<.*?>'#.表示除换行符以外的任意字符
print(re.sub(p, "", s, 0))#s表示上面的HTML字符串

其中.?这三个字符组合起来常用来表示任意不为换行的字符,这里面的?常用来表示非贪婪模式,这个名词我只在数据结构与算法的课本后面看到过,但老师没有讲。所以我刚刚看到的时候有点懵,后来明白了。以这个题目中的 <p>加分项:</p> 为例,<p>可用以<开头,以>结尾的规则匹配,但 <p>加分项:</p> 也可用这个表达式匹配,但后面这个显然不是我们想匹配到的,而如果使用的是<.>(不加?)默认的是贪心模式,能匹配到的字符串中的字符尽可能多(匹配最远的)。以上面的例子来看,匹配到的是 <p>加分项:</p> ,而加了?之后就是非贪心模式,能匹配到的字符串中的字符尽可能少(尽量匹配最近的),以上面的例子看,匹配到的是<p>。这是我对贪心模式和非贪心模式的一些理解,网上的很多正则表达式的题目中对于这个词都是只介绍概念,对于具体的含义阐述的比较少,初学者比较容易懵。

另外这个sub函数表示的是替换的意思,需要四个参数,从左往右依次是,匹配格式,替换之后字符,匹配的字符串,替换次数,如果是0,就表示全部替换。

另一个思路是如果我只是想通过格式匹配的方式把我需要的文本匹配出来,这个的pattern也很好写,但有坑,代码如下:

import re

p = r'>(.*?)</'#p为匹配的格式
print(re.findall(p, s))#调用re的findall方法,参数分别为格式和匹配字符串

p的代码和上面的比较类似,但多了一个括号,但正是这个括号才是这个格式的精髓,如果没有括号,会匹配出带有"<“和”/>",但有了括号就会匹配出不带开头和结尾的内容(只匹配括号中的内容)。如果不带括号匹配出的内容为

在这里插入图片描述
听上面的表述可能有些迷糊,但一看到具体的例子应该就秒懂了吧。

另外这个findall()函数,表示的是查找全部符合条件的字符串,并把他们组成一个列表,所以可以看到输出的内容是用[]括起来的。如果仔细看这种方式有一个缺点就是去除不掉<>形式的内容,如<br>,方法有很多可以转成字符串在匹配一次或者使用正则表达式匹配然后remove符合条件的选项,这里就不赘述了。findall可以说是正则表达式中使用最广泛的一个函数之一了,直译就是查找所有,而且把匹配出来的每一项数据放在一个列表中,便于后期对这些数据处理,毕竟很多情况下,不是查找到的字符串就完全符合要求了。

2.将以下网址提取出域名

http://www.interoem.com/messageinfo.asp?id=35
http://3995503.com/class/class09/news_show.asp?id=14
http://lib.wzmc.edu.cn/news/onews.asp?id=769
http://www.zy-ls.com/alfx.asp?newsid=377&id=6
http://www.fincm.com/newslist.asp?id=415
所谓域名就是如www.interoem.com这样的网址,仔细观察一下,我们肯定要找的是前面是http://,后面是/的部分,但以第二个为例,我如何确保匹配的是com后面的/,而不是class或者class09后面的/呢?我们想到了非贪心模式,代码如下:

import re

p = re.compile(r'http://(.*?)?/')# 其中第二个?表示的就是满足条件的最短字符串
print(p.findall(s))

格式p中的第二个?就是表示满足条件的最短字符串,也就是寻找的是第一个/前面的部分。

这里的正则表达式的写法和上面的有一些不一样。我来解释一下。正则表达式一般都有这两种写法,选择哪种看个人喜好。compile的字面意思是编译,而compile()函数表示的就是把后面一个字符串转成一个正则表达式的格式(pattern),这样p现在就是一个正则表达式的格式了,而上文的p只是一个满足正则表达式格式的字符串而已,所以这里的p可以直接调用re包下的所有函数,并且不需要传入满足正则表达式格式的字符串

3.将每行中的电子邮件地址分离出来并替换为你自己的电子邮件地址

s = ‘’‘693152032@qq.com, werksdf@163.com, sdf@sina.com
sfjsdf@139.com, soifsdfj@134.com
pwoeir423@123.com’’’
分析一下,这些字符串的一个特点是都有一个@和com,那么我们可以根据这个字符串的特点来匹配出电子邮箱。然后替换为自己的邮箱即可,代码如下:

import re

s = '''
693152032@qq.com, werksdf@163.com, sdf@sina.com
sfjsdf@139.com, soifsdfj@134.com
pwoeir423@123.com'''
p = re.compile(r'([^ ,\n].*?@.*?\.com)')
print(p.findall(s))
print(p.sub("abc@qq.com", s, 0))

其实如果只是想替换,而不是查找出这些邮箱,格式为p = re.compile(r'.*?@.*?\.')
如果使用这个格式,结果为:
在这里插入图片描述
可以看到后面的邮箱有对于的部分,所以这个方法只适用于替换。

4.使用正则表达式匹配合法的邮件地址

s = ‘’‘xiasd@163.com, sdlfkj@.com sdflkj@180.com solodfdsf@123.com sdlfjxiaori@139.com saldkfj.com oisdfo@.sodf.com.com’’’
先分析一下,正常的邮箱地址肯定是以数字或者字母开头,肯定有@,@后面也应该是数字或者字母,以.com结尾,所以代码如下:

import re

p = re.compile(r'\w+?@\w+?\.com')
print(p.findall(s))

5.总结

这些题目都属于看起来不是很难,但真正做出来,需要熟练掌握\w,.,\d,\s的区别,以及贪心模式,非贪心模式。正则表达式的练习题还有很多,这几个也只涉及一小部分,还有很多多个表达式混合之类更难的题目,还需要加油。

另外呢,正则表达式感觉真的很有用,可以帮助我们对爬取的信息中提取我们需要的信息,在数据分析处理方面超级好用。需要多加练习掌握。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值