文章目录

  • 预查
    • 正向预查:`?=`, `?!`
    • 负向预查:`?<=`, `?<!`/`?<!=`
    • 练习:网页小爬虫
  • 分组
    • 普通分组
    • 命名分组
    • 练习完善

昨天刚发现正则表达式的分组用法,故在此记录。


预查

正向预查:?=, ?!

?=: 检测包含此结尾的内容,但不捕获。

例:w+(?=\.com),检测以.com结尾的字符串,但返回结果中不包含.com.

*注:需引入re库,后面不再赘述。

print(re.findall(r'\w+(?=\.com)', 'baidu.com google.com csdn.net'))

输入结果:

['baidu', 'google']

?!: 检测不包含此结尾的内容,但不捕获。

例:Windows(?!95|98),检测不以95和98结尾的"Windows",返回结果中不包含Windows之后的内容。

print(re.match(r'Windows(?!95|98|NT|2000)', 'Windows95'))
print(re.match(r'Windows(?!95|98|NT|2000)', 'Windows10').group)

输出:

None
Windows

负向预查:?<=, ?<!/?<!=

?<=: 检测包含此开头的内容,但不捕获。

例:(?<=www\.)\w+,检测以www.开头的字符串,但返回结果中不包含开头。

print(re.findall(r'(?<=www\.)\w+', 'www.github.com cn.vuejs.org www.baidu.com'))

输出结果:

['github', 'baidu']

?<!?<!=: 等价,检测不包含此开头的内容,但不捕获。此处不再举例。

练习:网页小爬虫

需求:爬取douban.com中所有用div标签包裹的内容

import requests
import reheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
url = 'https://www.douban.com/'
http = requests.get(url, headers=headers)
reg = r'(?<=<div[^>]*>)\n*\w+\n*(?=</div>)'
result_list = re.findall(reg, http.text)
for result in result_list:print(result)

我们自然而然的想到左右用<?<=div...(任意字符)>...<?=/div>,然而结果却是:

re.error: look-behind requires fixed-width pattern

原来负向预查并不支持不定长字符串,我们需要找到更好的办法,不过现在我们可以先尝试不排除div标签,直接打印:

修改表达式为:reg = r'<div[^>]*>[^<]*</div>'

输出结果:

<div id="dale_anonymous_homepage_top_for_crazy_ad"></div>
<div id="dale_anonymous_homepage_right_top"></div>
<div id="dale_homepage_online_activity_promo_1"></div>
<div id="dale_anonymous_homepage_doublemint"></div>
<div class="side"></div>
<div id="dale_anonymous_homepage_movie_bottom" class="extra"></div>
<div class="author">〔日〕多利安助...</div>
<div class="author">〔日〕伊坂幸太...</div>
<div class="author">〔日〕池井户润...</div>
<div class="author">吴沚默</div>
<div class="author"></div>
...
<div class="title">你听过《东京爱情故事》吗?</div>
<div id="dale_anonymous_home_page_middle_2" class="extra"></div>
<div class="market-topic-pic"style="background-image:url(https://img3.doubanio.com/img/files/file-1513305186-3.jpg)"></div>
<div class="market-spu-pic"style="background-image: url(https://img3.doubanio.com/img/files/file-1546855945-0.jpg)"></div>
<div class="market-spu-pic"style="background-image: url(https://img3.doubanio.com/img/files/file-1545819571-0.jpg)"></div>
<div class="market-spu-pic"style="background-image: url(https://img9.doubanio.com/img/files/file-1513305186-4.jpg)"></div>
<div class="follow">3人关注</div>
<div class="datetime">4月4日 周六 19:30 - 21:30</div>
<div class="follow">1人关注</div>
<div class="datetime">12月21日 周六 - 4月12日 周日</div>
<div class="follow">5人关注</div>
<div id="dale_anonymous_home_page_bottom" class="extra"></div>

结果返回但非常杂乱,这就是我们之后需要改进的。


分组

普通分组

使用圆括号()表示分组。

这里介绍一下re.match()函数,这个函数会根据正则表达式从开头向后匹配,返回第一个符合的结果 (开头必须符合) 。它的返回值是一个object,object有group()方法和groups()方法。

  • group(): 返回正常匹配结果
  • groups(): 返回分组内容
print(re.match('(\w+)\.\w+\.(\w+)', 'www.baidu.com').group())
print(re.match('(\w+)\.\w+\.(\w+)', 'www.baidu.com').groups())

这里使用圆括号将网页URL的前缀作为一组,后缀作为一组,因此groups()会返回网页前后缀字符串。

输出结果:

www.baidu.com
('www', 'com')

命名分组

命名分组,顾名思义,可以给每个分组命名,返回值将以字典形式表示。

语法:?P<分组名>

例:

result = re.match('(?P<head>\w+)\.\w+\.(?P<tail>\w+)', 'www.baidu.com')
print(result['head'], result['tail'])

用head,tail命名网页前后缀,最终可通过访问字典的方式访问match返回值。

练习完善

之前的爬虫得到结果,却能杂乱,有个分组的知识我们就可以做出改进。

import requests
import reheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
url = 'https://www.douban.com/'
http = requests.get(url, headers=headers)
reg = r'<div[^>]*>([^<]*)</div>'
result_list = re.findall(reg, http.text)
index = 1
for result in result_list:if str(result).strip():print(str(index) + ". " + str(result).strip())index += 1

只做了少许修改:

  • 为reg标签包裹的内容加上括号(findall函数会以列表形式返回分组的所有内容,如果没有分组就返回匹配结果)
  • 对匹配结果使用strip()方法去除多余的空字符
  • 排除全空的结果,并为结果加上索引

输出结果:

1. 吃屎不忘拉屎人的日记
2. 〔日〕多利安助...
3. 〔日〕伊坂幸太...
4. 〔日〕池井户润...
5. 吴沚默
6. 免费
7. 免费
8. 免费
9. 免费
10. 「旅行」我想去精灵旅社度个假
11. 欧美丨在Uptown听Funk修个椰子皮
12. 日本民谣:我的歌,是用时间...
13. 「复古」音乐和情绪都不会过时
14. 给我一段音乐,推开看得见风...
15. 你听过《东京爱情故事》吗?
16. 3月25日 周三 19:30 - 21:30
17. 3人关注
18. 3月18日 周三 19:30 - 21:30
19. 3人关注
20. 4月4日 周六 19:30 - 21:30
21. 1人关注
22. 12月21日 周六 - 4月12日 周日
23. 5人关注

这次返回的结果就非常成功,简单利索。

正则表达式的进阶用法——预查与分组相关推荐

  1. ruby 正则表达式 使用正负预查

    例1:如果字符串New World后是Symphony 或 Dictionary 字符串New World将匹配, 但第三个单词不是匹配内容的一部分: s1="New World Dicti ...

  2. php正则表达式正向预查,javascript正则表达式-----正向预查

    前几篇有用到过, 但是未做深入学习,发现一篇很好的博文 转载自 javascript--正向预查 什么是正向预查?这里有腾讯招聘的一个例子: 如何给一串数字用千分制表示?比如9999999999变成9 ...

  3. 正则表达式: 正向预查和负向预查

    (?:pattern)匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用.这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用.例 ...

  4. (数据科学学习手札61)xpath进阶用法

    一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外(可参考我之前写的(数据科学学习手札50)基于P ...

  5. mysql 正则替换 换行,MySQL中使用replace、regexp进行正则表达式替换的用法分析

    本文实例讲述了MySQL中使用replace.regexp进行正则表达式替换的用法.,具体如下: 今天一个朋友问我,如果将数据库中查到的类似于"./uploads/110100_cityHo ...

  6. mysql替换首字母_MySQL中使用replace、regexp进行正则表达式替换的用法分析

    这篇文章主要介绍了MySQL中使用replace.regexp进行正则表达式替换的用法,结合具体实例形式分析了replace.regexp正则替换的使用技巧与相关注意事项,需要的朋友可以参考下 本文实 ...

  7. pandas进阶用法(一)筛选条件、多重索引、缺失值

    一篇比较好的pandas指南,适合已经熟悉pandas,并想掌握一些进阶用法的读者,不适合对pandas完全不了解的新人.文章大部分是Stack Overflow常见问题集合. pandas 官网 原 ...

  8. js mysql替换_MySQL中使用replace、regexp进行正则表达式替换的用法分析

    本文实例讲述了MySQL中使用replace.regexp进行正则表达式替换的用法.分享给大家供大家参考,具体如下: 今天一个朋友问我,如果将数据库中查到的类似于"./uploads/110 ...

  9. mysql正则替换_MySQL中使用replace、regexp进行正则表达式替换的用法分析

    本文实例讲述了MySQL中使用replace.regexp进行正则表达式替换的用法.分享给大家供大家参考,具体如下: 今天一个朋友问我,如果将数据库中查到的类似于"./uploads/110 ...

  10. python正则findall函数的用法_python中正则表达式 re.findall 用法

    python中正则表达式 re.findall 用法 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了r ...

最新文章

  1. mac下git与github简单使用
  2. 预处理_气体在线分析仪预处理系统的工作内容
  3. 三篇论文之bigtable
  4. request for KPI tile number display could not be executed for the second time
  5. (转载)Linux编程获取本机IP地址的三种方法
  6. java script的trim_Javascript中实现trim()函数的两种方法
  7. pytorch1.7教程实验——迁移学习训练卷积神经网络进行图像分类
  8. swoole 热重启
  9. C#中lock关键字的用法
  10. Effective C++笔记_条款35 考虑virtual 函数以外的其他选择
  11. 中国书信礼仪 (一)
  12. UISwitch详解
  13. 信息技术c语言试题,全国信息技术水平考试C语言考试试卷.doc
  14. 家里的钱都花哪儿了?做份支出记账表看看
  15. 游戏策划一类的,非常好
  16. torch tensor去掉1维_维E、激光都不是祛黄褐斑的好方法,坚持4件事,黄褐斑自动远离...
  17. 中国电子学会-全国青少年无人机技术等级考试标准 (1-2级)
  18. 「九章云极DataCanvas」完成C+轮融资, 用云中云战略引领数据智能基础软件升级
  19. python红楼梦词云_用Python读红楼梦之——二、词云美化
  20. if语句里面如果是赋值语句

热门文章

  1. 计算机机械制图试题及答案,机械制图及计算机绘图试卷和参考答案1.pdf
  2. 全国短信息中心号码一览
  3. linux解决笔记本pwm背光,担心PWM调光屏幕闪瞎眼?联想这些ThinkPad笔记本要注意...
  4. 服务器篇 使用Windows Server 2012R2搭建DHCP服务器-01
  5. matlab程序框图,求大神告知程序框图
  6. Android性能优化——启动优化简述
  7. 玩聚榜单-仿照Technorati的Popular频道
  8. kettle-java代码执行转换并获取步骤度量
  9. Frame Bounds 区别
  10. 股市行情图原来是这样实现的