正则表达式在网页文件中文本识别匹配的应用
写在前面
2021年第一篇博客。
博主在编程学习过程中,如果说有哪个问题学起来感觉最费劲,那就一定是正则表达式了,其灵活的表达式还有各种限定、扩展让人无比头大,而博主工作中用的正则表达式很少,所以总是记不住。
趁着最近在看《Python核心编程》这本书,第一章就是正则表达式,又系统的学习了一遍,虽然还是一知半解,但稍微又理解了那么一点点。顺便拿个例子来练练手,记录一下思路,忘记时再过来翻翻。
- 编程语言:Python3.7
- 编译器:Spyder
业务需求
博主的目标是从一个网页文档中提取一堆经纬度数据,先给大家看看文档的核心内容:
图片中,我框出来的红色部分的经纬度坐标是我要提取出来的东西,但我并非要提取成一个一个的点,而是一组一组的点,比如第一组就是我框出来的两个点4个坐标值,这两个点要在一个子列表中,这个子列表应该还有两个子列表,也就是那两个点的坐标。绕不绕,我觉得挺绕,上图片比较直观,我最后想要获取的结果如下图:
这样够清楚了吧。
需求讲明白了就开始写代码吧。
代码实现
网页标签提取
前面说了,我这是一个网页文档,什么东西处理网页文档最高效,那当然是beautifulsoup,我要提取的核心内容在网页的第6个script标签中,所以我要写一段下面的代码:
from bs4 import BeautifulSoup
import refilename = r'XXXX.html'
soup = BeautifulSoup(open(filename,encoding='utf-8'),features='html.parser')
soup = soup.find_all('script')
text = str(soup[5])
这是beautifulsoup的内容,我不细解释了,现在看看text的内容:
需要的内容在L.polyline(的下一行里面。
构建正则化表达式
分析一下字符串结构:
很明显,我要的东西是以.polyline(开头,换行之后的下一组经纬度坐标,所以标准的正则表达式应该是:
polyline(\n\s+([[.*?]])
下面我来解释一下这个正则表达式的意义:
- polyline这个可写可不写,因为我的文件里面可能还有其他点不是polyline的内容,所以我写上保证提取出来的点全是polyline里面的内容;
- \ (匹配左圆括号;
- \n匹配换行;
- \s+匹配一个或者多个空格,\s是匹配空格,+是匹配其次或多次;
- ([[.*?]])这一组比较关键,首先我有一组圆括号()并没有使用转义符\,那肯定不是匹配圆括号了,圆括号在正则表达式中可以实现下面任意一个(或者两个)功能,一是对正则表达式进行分组,二是匹配子组,这里就是匹配子组了;我写了两组[[及对应的]]用来表示我要匹配的字符串前后要有两个方括号,. *?用来匹配任意长度的字符串,其中?表示最短匹配,也就是说匹配到最短符合的那一个,如果不写?就成了贪婪匹配,匹配到最长的那个。
解释完了,那在Python里面到底该怎么写呢?看代码
res2 = re.findall('polyline\(\n\s+(\[\[.*?\]\])', text, re.DOTALL)
代码中我传入参数re.DOTALL,这又是个啥意思呢?
re.DOTALL表示.可以匹配换行符(\n),作用是能真正的匹配所有字符,默认情况下,正则表达式中的dot(.),表示所有除了换行的字符,加上re.DOTALL参数后,就是真正的所有字符了,包括换行符(\n)。
换句话说,如果我不传入re.DOTALL参数,.就匹配不到文档中的换行符。
还有个问题我得解释,为啥我这里使用的是最短匹配呢,也就是为啥我写的是. *?而非. *,正常情况下. *应该也是能匹配任意长度的字符串的,那正是因为我传入了re.DOTALL参数,导致我的正则表达式可以识别换行符了,那样如果用贪婪匹配的话,它就能找到最长符合的那个字符串,包括已经换行的内容,这显然不是我要的目的。
其实还可以这么写:
res2 = re.findall('polyline\(\n\s+(\[\[.*\]\])', text)
使用贪婪匹配,但是不传入re.DOTALL参数,那我匹配出来的永远只是那一行里面的内容,匹配结果一样。
好了,看看我匹配出来的是啥玩意儿吧:
字符串解析
对是对了,但是列表里面的内容全是字符串,而非有用的经纬度坐标,所以我还要对字符串进行处理,写一段下面的代码:
for i in range(len(res2)):res2[i] = res2[i].replace('[[', '').replace(']]', '').replace(' ','').split('],[')for j in range(len(res2[i])):res2[i][j] = res2[i][j].split(',')for k in range(len(res2[i][j])):res2[i][j][k] = float(res2[i][j][k])
这段是数据清洗的内容,不详细讲了。
完整代码
from bs4 import BeautifulSoup
import refilename = r'C:\Users\HP\Desktop\在办工作\25-所级课题研究\典型道路事故\钱荣路.html'
soup = BeautifulSoup(open(filename,encoding='utf-8'),features='html.parser')
soup = soup.find_all('script')
text = str(soup[5])# 第二种匹配方法
# 未转义的一组圆括号用来分组匹配,.*?用来匹配任意长度的字符串,其中?表示最短匹配,
# 也就是说匹配到最短符合的那一个,如果不写?就成了贪婪匹配,匹配到最长的那个,
# re.DOTALL表示.可以匹配换行符(\n),作用是能真正的匹配所有字符
res2 = re.findall('polyline\(\n\s+(\[\[.*?\]\])', text, re.DOTALL)
# 上面取出来的列表里的元素是字符串,还是需要转换才行
for i in range(len(res2)):res2[i] = res2[i].replace('[[', '').replace(']]', '').replace(' ','').split('],[')for j in range(len(res2[i])):res2[i][j] = res2[i][j].split(',')for k in range(len(res2[i][j])):res2[i][j][k] = float(res2[i][j][k])
注释里可以看到,这是我的第二种匹配方法,第一种写的,简直一塌糊涂,就不丢人现眼了。
写在后面
正则表达式是编程人员需要掌握的一个重点知识点,这篇博客是我在摸索很久后一直感觉不得要领,然后向读研时的同袍学习后总结的,学习路上需要有个领路人,虽然已经很久不见,但是依然是值得信赖的好基友。
努力学习,共勉。
正则表达式在网页文件中文本识别匹配的应用相关推荐
- 使用正则表达式查找Word文件中AABB和ABAC形式的成语
使用正则表达式查找Word文件中AABB和ABAC形式的成语 1.实验目的 (1)熟练安装Python扩展库python-docx. (2)了解Word文件的内容组织方式. (3)熟悉Python标准 ...
- Python批量设置pptx文件中文本框边框与填充样式(含20分钟视频讲解)
近期会议: 10月30-11月1日 全国高校Python课程高级研修班(苏州) 推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清 ...
- html让文本框左剧中对齐_Python批量设置pptx文件中文本框边框与填充样式(含20分钟视频讲解)...
近期会议:10月30-11月1日 全国高校Python课程高级研修班(苏州)推荐图书:<Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清华大学 ...
- python批量提取pdf的数据_Python批量提取PDF文件中文本的脚本
本文实例为大家分享了Python批量提取PDF文件中文本的具体代码,供大家参考,具体内容如下 首先需要执行命令pip install pdfminer3k来安装处理PDF文件的扩展库. import ...
- 使用Python批量修改PPTX文件中文本框格式
问题描述:最近正在整理Python教材的配套PPT,原来的PPT是4:3的,考虑到现在很多屏幕都是宽屏的,于是打算重新整理一下.对于正常的幻灯片,直接在"页面设置"中修改一下就可以 ...
- freemarker模板文件中文本域(textarea)的高度自适应实现
2019独角兽企业重金招聘Python工程师标准>>> freemarker模板文件中实现文本域(textarea)的高度自适应实现. 从网上找的大部分办法中很多方法兼容性并不好,要 ...
- FileLocatorPro正则表达式批量搜索文件中的字符串
FileLocatorPro_x64 工具可以按正则表达式批量搜索路径下多个文件中含有的特定字符串,类似的效果是在Linux上使用 grep 命令,例如我想搜索含有openssl组件的程序,使用效果如 ...
- 【正则表达式高级day01】正则表达式概述+在一个文件中,查找出itcast开头的语句+在一个文件中,找到含有itcast的语句+在一个文件中,找到邮箱为163或者126的所有邮件地址
文章目录 正则表达式概述 思考 场景1:在一个文件中,查找出itcast开头的语句 场景:在一个文件中,找到含有itcast的语句 场景:在一个文件中,找到邮箱为163或者126的所有邮件地址 正则表 ...
- Python批量提取Excel文件中文本框组件里的文本
开学第一课:拜托,一定不要这样问Python问题 中国大学MOOC"Python程序设计基础"免费学习地址 2020年秋季学期Python教材推荐与选用参考 推荐图书: <P ...
- 网页开发中文本编辑器UEditor的使用
首先看一下效果图: 首先我们需要来认识下UEditor,它是由百度web前端研发部开发所见即所得富文本web编辑器,并且是基于BSD协议的开源产品,允许自由使用和修改,开源就意味着可以自己来定制这个编 ...
最新文章
- MFC中设备描述表dc的使用
- JavaScript实现冒泡排序 可视化
- php 以-截取剩余的字符串_10分钟从PHP到Python
- python发邮件11002_【python发送zabbix报警邮件,SSL版本】mailman.py
- laravel允许所有网站进行跨域操作
- 大屏某区域滚动效果循环
- 信息学奥赛一本通 2024:【例4.10】末两位数
- centos7搭建hadoop
- 锂电设备商联赢激光6月22日科创板上市
- C++ 中的Singleton 类的实现
- 原生js实现选中所有的checkbox
- 欧莱雅迎来入华25周年;万代南梦宫集团将启用新logo | 美通企业日报
- B站小甲鱼Python基础学习课堂笔记
- ubuntu将主文件夹的文件夹中文名称改为英文
- 详解_阿里云FPGA服务器f3实例RTL开发最佳实践脚本代码
- 前端架构,有什么能做的?
- 电话键盘 电脑键盘与标点符号英文读法
- WIN7下弹出应用程序兼容性助手解决
- 荣耀20搭载鸿蒙,荣耀20新机发布 搭载鸿蒙系统荣耀20详细参数
- BZOJ4833: [Lydsy1704月赛]最小公倍佩尔数-数论