Python爬虫(二)正则表达式
目录
正则表达式语法规则
字符
预定义字符集
数量词
贪婪和非贪婪
边界匹配(不消耗匹配字符串中的字符)
逻辑、分组
Python re模块介绍
引入模块
正则检索
正则分割字符串
字符串替换
分组引用
匹配中文
正则表达式语法规则
百度百科简介:正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配的一个或多个字符串。
字符
字符 | |
---|---|
. | 匹配一个任意字符,换行符除外 |
\ | 转义字符,把带有特殊含义的字符转换成无意义字符 |
[...] | 字符集,匹配其中的任意一位。a[012]b,可以匹配a0b,a1b,a2b;可以指定范围,a[0-9]b;a[0-9a-zA-Z] |
^ |
取反,需要放在[]里面的最前面,a[^0-9]b 表示匹配一个非数字的任意字符 如果要匹配数字或者^字符,a[0-9^]b或者写成a[\^0-9]b |
预定义字符集
\d | 匹配数字,等同于[0-9] |
\D | 匹配非数字,等同于[^0-9] |
\s | 匹配空白字符,等同于[\n\t\r\f\v] ,换行、空格、\f换页符,\v 垂直制表符 |
\S | 匹配非空白字符 |
\w | 匹配单词字符(数字、字母、下划线),等同于[0-9a-zA-Z_] |
\W | 匹配非单词字符 |
数量词
* | 匹配前一个字符0或者无限次 |
+ | 匹配前一个字符1或者无限次 |
? | 匹配前一个字符0次或者1次,一般和括号()组合使用 |
{M} | 匹配前一个字符M次,{N,M}匹配N-M次,{M,} 最少M次,无上限 |
贪婪和非贪婪
贪婪:再整个表达式匹配成功的前提下,尽可能多的匹配
非贪婪:在整个表达式匹配成功的前提下,尽可能少的匹配
贪婪 | .*或者\s* 贪婪匹配,会一直匹配到最后不能匹配的位置 |
非贪婪 | .*? 非贪婪匹配,会匹配每一次出现的结果 |
例:<p>123</p><p>abcde</p> ,使用贪婪和非贪婪模式匹配这个字符串。
<p>.*</p> 贪婪匹配,*号会匹配到尽可能多的东西,匹配整个123</p><p>abcde,最后匹配结果只有一个结果集,就是整个字符串。
<p>.*?</p> 非贪婪匹配,会匹配每一次出现的结果。匹配的结果有两个:<p>123</p>和<p>abcde</p>。
边界匹配(不消耗匹配字符串中的字符)
^ | 匹配字符串的开头 |
$ | 匹配字符串的结尾,空格回车也会参与匹配 |
\A | 字符串的开头(Python中独有的写法) |
\Z | 字符串的结尾(Python中独有的写法) |
\b |
匹配单词和非单词的边界,单词和非单词的交界。(单词字符包括数字、字母、下划线、汉字) tom,do you have time tomorrow 匹配tom人名,tom\b tomorrow tom后面o是单词,不满足\b的要求 |
\B | 匹配要么都是单词,要么都是非单词 |
逻辑、分组
| | 左右表达式任意匹配一个。尝试先匹配左边再匹配右边。经常和括号配合使用,hello (aaa|bbb) |
( ) | 括号代表分组,或者一个整体。 |
\num |
引用第num个分组 分组示例: Anni like Anni John like Jerry \1代表引用第一个分组的值,做搜索。 意思是把like前面的字符串用到后面\1的地方,a like b,其中b的值是和a一样的, 结果是检索出 Anni like Anni |
正则练习
在线练习正则表达式的网址: http://tool.oschina.net/regex/
1、用正则匹配如下网址
http://www.baidu.com
https://www.sina.com.cn
https://www.baidu.com/s?wd=python&name=anni
ftp://www.antvv.com
https://www.antvv.com?cate=3
(http|https|ftp)://www\.\w+\.(com\.cn|com|cn|net|gov)(/\w+)*(\?\w+=\w+)?
2、电话号码匹配(11位)
+86 13456789012
18999245678
12341134
(\B(\+86 )?|\b)1[3-9]\d{9}
3、身份证 (18位,最后一位可能是X)
368756483729876657
36875648372987665X
3687564837298766571
3687564837298766573X
\b\d{17}(\d|X)\b
4、匹配年份1990-2019
1990
2019
1989
2020
2010
20101
22010
\b(199|20(0|1))\d\b
Python re模块介绍
引入模块
import re
reg=re.compile('正则') 编译正则表达式,之后就可以通过该对象匹配
正则检索
result=reg.match() 从文本中匹配正则表达式,从字符串第一个位置开始匹配,只匹配一次,匹配到了就返回match对象,否则返回None。
result.group() 从匹配到的对象中取出分组,如果有分组则传入分组编号取出相应组的返回值,如果没有分组不需要传或者传0。
#-*- coding: UTF-8 -*-
import re# 取出手机号前三位和后四位
phone="13123456789"
phone_reg=re.compile("(1[3-9]\d)(\d{4})(\d{4})")
result=phone_reg.match(phone)
print(result.group(1))
print(result.group(3))# 打印结果
# 131
# 6789
正则表达式:(1[3-9]\d)(\d{4})(\d{4}),把手机号分成了三组,每个()是一个分组,如果取第一分组就用group(1)。
如果不取分组的信息,取整个正则匹配的数据,则group不需要传参数,或者group(0)。
#-*- coding: UTF-8 -*-
import re
phone="13123456789"
phone_reg=re.compile("(1[3-9]\d)(\d{4})(\d{4})")
result=phone_reg.match(phone)
print(result.group())
print(result.group(0))# 打印结果:
# 13123456789
# 13123456789
reg.search() 从字符串的任意位置开始搜索,match的升级版,只匹配一次。
如果上个例子中,把手机号改掉,让 phone="我的手机号是13123456789",用match函数是无法检索出来的。
#-*- coding: UTF-8 -*-
import re
phone="我的手机号是13123456789"
phone_reg=re.compile("(1[3-9]\d)(\d{4})(\d{4})")
result=phone_reg.match(phone)
print(result)# 打印结果
# None
改成用search就可以了
#-*- coding: UTF-8 -*-
import re
phone="我的手机号是13123456789"
phone_reg=re.compile("(1[3-9]\d)(\d{4})(\d{4})")
result=phone_reg.search(phone)
print(result.group())# 打印结果
# 13123456789
reg.findall() 任意位置搜索,匹配多次。匹配所有满足条件的字符。
返回的是列表,如果正则里面有分组,返回元组形式包装的分组返回信息;
如果没有分组,列表里面直接是返回值。
在分组开始的括号后面加上?:代表该括号不作为一个分组
str='''我的名字是王小明,我的手机号是13114567890,我的身份证号是330721197010040515。我的名字是孙其绥,我的手机号是13114567890,我的身份证号是330702197108020812。我的名字是孙群领,我的手机号是13114567890,我的身份证号是33072419770516031X。
'''
如何检索出上面str的所有手机号码呢?
#-*- coding: UTF-8 -*-
import re
str='''我的名字是王小明,我的手机号是13114567890,我的身份证号是330721197010040515。我的名字是孙其绥,我的手机号是13114567890,我的身份证号是330702197108020812。我的名字是孙群领,我的手机号是13114567890,我的身份证号是33072419770516031X。
'''
phone_reg = re.compile("手机号是(1[3-9]\d{9}),我的")
result = phone_reg.findall(str)
print(result)# 打印结果
# ['13114567890', '13114567890', '13114567890']
现在可以检索出手机号码了,那么思考下,怎么检索出每个号码的前3位和后四位呢?结合上面的例子思考3秒钟。
#-*- coding: UTF-8 -*-
import re
str='''我的名字是王小明,我的手机号是13114567890,我的身份证号是330721197010040515。我的名字是孙其绥,我的手机号是13114567890,我的身份证号是330702197108020812。我的名字是孙群领,我的手机号是13114567890,我的身份证号是33072419770516031X。
'''
# 使用分组,如果不想让中间四位检索出来,就加?:使第二个不作为一个分组
phone_reg = re.compile("手机号是(1[3-9]\d)(?:\d{4})(\d{4}),我的")
result = phone_reg.findall(str)
print(result)# 打印结果
# [('131', '7890'), ('131', '7890'), ('131', '7890')]
reg.finditer() 匹配所有满足条件的,返回一个可迭代对象
遍历返回的是match对象,用group获取值
#-*- coding: UTF-8 -*-
import re
str='''我的名字是王小明,我的手机号是13114567890,我的身份证号是330721197010040515。我的名字是孙其绥,我的手机号是13114567890,我的身份证号是330702197108020812。我的名字是孙群领,我的手机号是13114567890,我的身份证号是33072419770516031X。
'''
phone_reg = re.compile("手机号是(1[3-9]\d)(?:\d{4})(\d{4}),我的")
result = phone_reg.finditer(str)
for once in result:print(once.group(1)+"***"+once.group(2))# 打印结果
# 131***7890
# 131***7890
# 131***7890
正则分割字符串
split() 通过正则表达式分割字符串,结果返回一个list。
#-*- coding: UTF-8 -*-
import re
str2="唱_跳,rap_篮球"
# 同时用多种字符进行分割
regex_sp = re.compile(",|_")
result = regex_sp.split(str2)
print(result)# 返回结果
# ['唱', '跳', 'rap', '篮球']
字符串替换
sub("替换字符",目标str,替换次数) 字符串替换,替换次数不设置的话,默认替换所有。
bad_str_reg = re.compile("[><\?\"/\|\\\\:\*]")
bad_str_reg.sub("目标字符",str)
subn() 字符串替换后返回替换次数和替换过的字符串
用re去调用的话:
re.sub(正则表达式,"替换字符",目标str,替换次数)
#-*- coding: UTF-8 -*-
import re
filename = "/清\华|大<学:校*花>校?花\"名.jpg"
result = re.sub("[><\?\"/\|\\\\:\*]","",filename)
print(result)
result2 = re.sub("[><\?\"/\|\\\\:\*]","",filename,5)
print(result2)
result3 = re.subn("[><\?\"/\|\\\\:\*]","",filename)
print(result3)# 打印结果
# 清华大学校花校花名.jpg
# 清华大学校*花>校?花"名.jpg
# ('清华大学校花校花名.jpg', 9)
分组引用
\num 引用分组
#-*- coding: UTF-8 -*-
import re
phone_num="13114567890"
phone_reg=re.compile("(1[3-9]\d)(\d{4})(\d{4})")
result=phone_reg.sub("\\1****\\3",phone_num)
# 第一分组+****+第三分组
print(result)# 打印结果
# 131****7890
匹配中文
如何获取一段字符串中的所有中文内容。
[\u4e00-\u9fa5]
或者
[一-龥]
(从第一个中文“一”匹配到最后一个中文“龥”(yù))
#-*- coding: UTF-8 -*-
import re
str3="我的名字是王小明,我的手机号是13114567890,我的身份证号是330721197010040515。"
print(re.findall("[\u4e00-\u9fa5]+",str3))
print(re.findall("[一-龥]+",str3))# 打印结果
# ['我的名字是王小明', '我的手机号是', '我的身份证号是']
# ['我的名字是王小明', '我的手机号是', '我的身份证号是']
Python爬虫(二)正则表达式相关推荐
- 05、Python爬虫之正则表达式常用方法(超全)
文章目录 前言 一.search()函数 二.match()函数 三.compile()函数 四.findall()函数 五.sub()函数 六.subn()函数 七.split()函数 八.补充说明 ...
- [Python爬虫] 二、爬虫原理之定义、分类、流程与编码格式
往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 一.爬虫的定义.分类和流程 爬虫定义 网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟浏览器发送网络请求,接收请求 ...
- Python爬虫:正则表达式?就这
前言 当你点开文章的时候,我就知道这次的标题有点装逼了,哈哈,不过不要紧,还好我写的都是干货. 正则表达式是处理字符串的强大工具,它有自己特定的语法结构,可以实现字符串的检索.替换.匹配验证. 案例引 ...
- Python全栈开发-Python爬虫-03 正则表达式详解
正则表达式 一. 什么是正则表达式 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定 ...
- Python爬虫(二)——多线程下载壁纸图片(星月设计网)
文章目录 Python爬虫--多线程下载图片(星月设计网) 目的: redis存储结构: 使用到的python库: 1. 导入相关库 2. 连接redis 3.爬虫主要类及函数 4.爬取结果: Pyt ...
- Python 爬虫二 requests模块
requests模块 Requests模块 get方法请求 整体演示一下: import requestsresponse = requests.get("https://www.baidu ...
- Python爬虫笔记——正则表达式
一.python中的正则--re模块 1.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序员们可以直接调用来实现正则匹配. 正则表达式模式被编译成 ...
- Python爬虫(二)_urllib2的使用
所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地.在Python中有很多库可以用来抓取网页,我们先学习urllib2. urllib2是Python2.x自带的模块(不需要 ...
- 利用python爬虫(part3)--正则表达式
学习笔记 文章目录 正则表达式 re模块的使用 正则表达式元字符 贪婪匹配和非贪婪匹配 贪婪模式 非贪婪模式 正则表达式分组 正则表达式 re模块的使用 re模块在爬虫中常用的方法: re.finda ...
- python爬虫之 ---------------- 正则表达式(1)
正则表达式 正则表达式简历: 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. 在python中通过内置的re库来使用正则表达式,它提供了所有正则表达式的功能. re ...
最新文章
- c#读写XML文件 (转)
- P2502 [HAOI2006]旅行
- 利用注解 + 反射消除重复代码(Java项目)
- c语言中的目标程序的正确含义,C语言程序设计练习题整理要点.doc
- 计算机网络管理员五级试题,计算机网络管理员考试试题库和答案.doc
- scrum回顾_3步开好回顾会 | IDCF FDCC认证学员作品
- 【渝粤教育】电大中专工程图学基础 (3)作业 题库
- php+mysql记事本_一个简单记事本php操作mysql辅助类创建
- 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树
- 在jboss上部署web应用
- 阿里2019财年收入达3768.44亿元 盘前涨幅一度超4%
- java 怎么从date取得年份
- BigDecimal与double
- python求函数零点,在函数零点问题中求解参数范围
- ecshop插件-免费ecshop插件-ecshop插件应用中心
- Windows常见基本进程三:dumprep or dumprep进程(Dump Reporting Tool启动项)
- 教你简单3步搞定——微信快速添加个人表情包
- Python - 【珍藏】知识清单及文章链接
- etr2模式,时力高HXD1C转换开关KRGV+ETR2
- 【渝粤教育】电大中专学习指南作业 题库