Python "爬虫"出发前的装备之一正则表达式
1. 正则表达式
正则表达式是一种模板表达式语言
通过定义规则去匹配、查找、替换、分割一个长字符串中特定的子字符信息。
如在一篇文章中查找出所有合法的电子邮箱地址,则可以先用正则表达式定义一个电子邮箱规则,然后再使用这个规则在整个字符串中查找。
爬虫程序一般都会借助正则表达式定义的规则在爬出来的内容中做精细化筛检。
正则表达式有自己独立于其它计算机语言的语法结构,且大部分计算机编程语言都提供有对正则表达式的支持。如 Java、JavaScript、python……
1.1 正则表达式语法
普通字符匹配规则
普通字符指字母、数字、汉字、下划线、以及没有特殊定义的标点符号。正则表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
如需在 “This is my love” 中匹配 “love” 子字符串,则表达式就是 "love"。
转义符匹配规则
在正则表达式语法中有很多字符除了其自身意义外,还有语法赋予的特殊意义。如:^、$、?、*……
如在 This is my lo$ve 中匹配出 lo$ve,则表达式不能写成 lo$ve。默认情况下,正则表达式的语法解析器不会把 $ 其视为其自身含义,而是把它解析成特定的含义(边界定义)。所以表达式中需使用转义符 \ 进行转义。需写成 lo$ve
另,有些无法输入的字符也需要通过转义符进行转义:
| \n | 代表换行符 |
|---|---|
| \t | 制表符 |
| \ | 代表**本身 |
| ^ ,$,.,(, ) , {****, } , ? , + , * , | ,[, ] | 匹配这些字符本身 |
标准字符集
如果需要在一个字符串中匹配一些具有共同特征的字符,则可以使用字符集规则,如在一个 Firse 1,Second 2,Three 3……字符串中匹配所有数字或所有空格。
| \d | 任意一个数字,****0~9 中的任意一个 |
|---|---|
| \w | 任意一个字母或数字或下划线,也就是 AZ,az,0~9,_ 中任意一个 |
| \s | 包括空格、制表符、换行符等空白字符的其中任意一个 |
| . | 小数点可以匹配任意一个字符 |
Tip: 标准字符集是区分大小写的
大小写都能描述特定的字符群体,互为相反关系。如 \d 指任意数字,\D 指除了数字之外的其它字符。
自定义字符集合
用户可以定义自己的字符集合,用来满足开发时的特定需要,如在 123456789ABaCbDEcdFG 中查找或匹配奇数和小写字母。
自定义集合使用 [ ] 来定义。
| [ab5@] | 匹配 "a" 或 "b" 或 "5" 或 "@" |
|---|---|
| [^ abc] | 匹配 a,b,c 之外的任意一个字符 |
| [f-k] | 匹配 "f"~"k" 之间的任意一个字母 |
| [^A-F0-3] | 匹配 "A""F","0""3" 之外的任意一个字符 |
正则表达式中的特殊符号,如果被包含于中括号中,则失去特殊意义,但 \ [ ] : ^ - 除外。
比如:[\d.-+],将可以匹配数字,小数点和 + - 符号。(小数点和 + 号失去语法赋予的意义)
修饰匹配次数的特殊符号
| {n} | **表达式重复 n次 ** |
|---|---|
| {m,n} | 表达式至少重复 m 次,最多重复 n 次 |
| {m,} | 表达式至少重复 m 次 |
| ? | 匹配表达式 0 次或者 1 次,相当于 {0,1} |
| + | 表达式至少出现 1 次,相当于 {1,} |
| ***** | 表达式不出现或出现任意次,相当于 {0,} |
- 贪婪模式:匹配字符越多越好
- 非贪婪模式:匹配字符越少越好,需要在修饰匹配次数的特殊符号后再加上一个 "?" 号
正则表达式的语法相对而言较简单,可以在使用过程中查阅相关文档
2. Python 中使用正则表达式
Python 提供有正则表达式模块,使用时只需要导入即可。
import re
re 模块中提供了几个常用方法
- re.match(p,text) 方法:匹配成功则返回一个 Match 匹配对象,匹配不成功则返回一个 None
- re.search(p,text) 方法:在 text 字符串中查找匹配的内容,如果找到则返回第1个匹配的 Match 对象,否则返回None
- re.findall() 方法:在 text 字符串中查找所有匹配的内容。如果找到,返回所有匹配的字符串列表。否则,返回None
- re.sub(p,newstr,oldstr,count=0) 方法:替换匹配的子字符串。返回值是替换之后的字符串
- re.split(p,string,maxsplit=0) 方法: 对字符串进行分割。返回值字符串列表
2.1 re.match 方法
方法原型说明:
import re
re.match(pattern, string, flags=0)
- pattern 正则表达式
- string 要匹配的字符串
- flags 用来控制正则表达式的匹配方式,如是否区分大小写、多行匹配等
Tip:从字符串起始位置匹配,如果从起始位置匹配不了,就返回 none。
案例一:
import re
m = re.match('www', 'www.baidu.com')
print ("结果: ", m)
print ("起始与终点:", m.span())
print ("起始位置:", m.start())
print ("终点位置:", m.end())
输出结果:
结果: <re.Match object; span=(0, 3), match='www'>
起始与终点: (0, 3)
起始位置: 0
终点位置: 3
案例二:
import re
line = "You are just the person I want to see"
m = re.match(r'(.*) are (.*?) the', line)
print ("结果:", m)
# groups() 返回匹配的字符列表
for res in m.groups():
print(res)
print("匹配上的完整子字符串",m.group(0))
# 和 groups() 中的结果一致
print("第一个匹配上的字符:",m.group(1))
print("第一个匹配上的字符:",m.group(2))
2.2 re.search 方法
原型说明:
import re
re.search(pattern, string, flags=0)
Tip: re.search 方法的参数语义和 re.match 方法相同
re.match 方法只能从字符串的起始位置进行匹配 ,re.search扫描整个字符串并返回第一个成功的匹配。其它的性质则是一样的。
案例:
import re
m_match = re.match('baidu', 'www.baidu.com')
m_search = re.search('baidu', 'www.baidu.com')
print ("re.match 输出结果:",m_match)
print ("re.search 输出结果:",m_search)
输出结果
re.match 输出结果: None
re.search 输出结果: <re.Match object; span=(4, 9), match='baidu'>
2.3 re.findall 方法
原型说明
import re
re.findall(pattern, string, flags=0)
Tip :re.findall 方法的参数说明和 re.search 相同
- re.search 方法匹配到一个结果后便结束
- re.findall 顾名思义,会找到所有符合规则的匹配项,并以列表类型返回
案例:
import re
#返回 Match 类型
re_match = re.match('[0-9]+', '12345 is the first number, 23456 is the sencond')
#返回 Match 类型
re_search = re.search('[0-9]+', 'The first number is 12345, 23456is the sencond')
# #返回列表类型
re_findall = re.findall('[0-9]+', '12345 is the first number,23456 is the sencond')
print ("re.match:",re_match.group())
print ("re_search",re_search.group())
print ("re_findall:",re_findall)
输出结果:
re.match: 12345
re_search 12345
re_findall: ['12345', '23456']
2.4 re.sub 方法
方法原型说明:
import re
re.sub(pattern, repl, string, count=0, flags=0)
- pattern是正则表达式
- repl是用于替换的新字符串
- string是即将被替换的旧字符串
- count是要替换的最大数量,默认值为零
import re
p=r'\d+'
text="AB12CD34EF56HK"
replace_text=re.sub(p,' ',text)
print("默认替换所有:",replace_text)
replace_text=re.sub(p,' ',text,count=1)
print("仅替换一次:",replace_text)
replace_text=re.sub(p,' ',text,count=2)
print("仅替换二次:",replace_text)
输出结果:
默认替换所有: AB CD EF HK
仅替换一次: AB CD34EF56HK
仅替换二次: AB CD EF56HK
2.5 re.split 方法
方法原型说明:
import re
re.split(pattern, string, maxsplit=0, flags=0)
- pattern是正则表达式
- string是要分割的字符串
- maxsplit是最大分割次数。默认值为零,表示分割次数没有限制
案例:
import re
p = r'\d+'
text = 'AB12CD34EF56GH'
lst = re.split(p, text)
print("默认对整个字符串进行分割:", lst)
lst = re.split(p, text, maxsplit=1)
print("仅分割一次:", lst)
lst = re.split(p, text, maxsplit=2)
print("分割二次:", lst)
输出结果
默认对整个字符串进行分割: ['AB', 'CD', 'EF', 'GH']
仅分割一次: ['AB', 'CD34EF56GH']
分割二次: ['AB', 'CD', 'EF56GH']
总结
python 提供的 re 模块中有很多方法可借助正则表达式方便、快捷地完成字符串的相关操作,对于爬虫程序来讲正则表达式是其不可忽视的一部分。
Python "爬虫"出发前的装备之一正则表达式的更多相关文章
- Python "爬虫"出发前的装备之二数据先行( Requests 模块)
1. 概念 爬虫不是动物,而是一种计算机程序. 这种程序有自己特定的功能,能按照使用者给定的一系列规则自行浏览万维网并获取需要的信息.此类程序被称为 网络爬虫(web crawler) 或 网络蜘蛛( ...
- python爬虫之小说网站--下载小说(正则表达式)
python爬虫之小说网站--下载小说(正则表达式) 思路: 1.找到要下载的小说首页,打开网页源代码进行分析(例:https://www.kanunu8.com/files/old/2011/244 ...
- python爬虫—爬取英文名以及正则表达式的介绍
python爬虫—爬取英文名以及正则表达式的介绍 爬取英文名: 一. 爬虫模块详细设计 (1)整体思路 对于本次爬取英文名数据的爬虫实现,我的思路是先将A-Z所有英文名的连接爬取出来,保存在一个cs ...
- python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?
现在 你已经会使用 python 模拟浏览器 进行一些 Http 的请求了 那么请求完之后 服务器返回给我们一堆源代码 我们可不是啥都要的啊 我们是有原则的 我们想要的东西 怎么能一股脑的啥都往自己兜 ...
- Python爬虫入门(7):正则表达式
下面就开始介绍一个十分强大的工具,正则表达式! 1.了解正则表达式 正则表达式是对字符串操作的一种公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串” ...
- Python爬虫(十一)_案例:使用正则表达式的爬虫
本章将结合先前所学的爬虫和正则表达式知识,做一个简单的爬虫案例,更多内容请参考:Python学习指南 现在拥有了正则表达式这把神兵利器,我们就可以进行对爬取到的全部网页源代码进行筛选了. 下面我们一起 ...
- 【Python爬虫实战--3】html写正则表达式
以下是要爬虫的html内容: <div class="article block untagged mb15" id='qiushi_tag_113452216'> & ...
- python爬虫知识点总结(五)正则表达式
在线正则表达式匹配:http://tool.oschina.net/regex 正则表达式学习:https://c.runoob.com/front-end/854 一.什么是正则表达式? 常见匹配模 ...
- python爬虫07 | 有了 BeautifulSoup ,妈妈再也不用担心我的正则表达式了
我们上次做了 你的第一个爬虫,爬取当当网 Top 500 本五星好评书籍 有些朋友觉得 利用正则表达式去提取信息 太特么麻烦了 有没有什么别的方式 更方便过滤我们想要的内容啊 emmmm 你还别说 还 ...
随机推荐
- 以太 ip tcp udp 三次握手的理解
以太帧: 1.前导码(7字节):使接收器建立比特同步. 2.起始定界符SFD(1字节):指示一帧的开始. 3.目的地址DA(6字节):指出要接收该帧的工作站. 4.源地址SA(6字节):指示发送该帧的 ...
- golang中的数组
1. 数组的声明 package main import "fmt" func main() { // 数组:定长且元素类型一致的数据集合 // 方式一:先声明在赋值,声明时内存中 ...
- Ubuntu SVN 搭建
SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subversion ...
- PC端实用正版软件推荐
首先介绍一下背景,我本人是一个软件工程师,所以对电脑上很多软件使用都有要求,这里将个人觉得好用的一些软件分享给大家: 1. Typora 对于长写本地笔记.网络博客的人,对 MarkDown 格式应该 ...
- 从新建文件夹开始构建ShadowPlay Engine游戏引擎(6)
本篇序言 在经历了为期很长时间的调试以及思维纠错后,我们可以开始实现我们的内存管理模块了,我在前面说过如果各位要继续跟着学习的话可能会需要一定的计算机组成原理和操作系统的知识,不过在莽代码的过程中,我 ...
- react直接使用bootstrap失效的原因
react用的是className!而不是class~
- maven中profiles使用详解
使用的场景 常常遇到一些项目中多环境切换的问题.比如在开发过程中用到开发环境,在测试中使用测试环境,在生产中用生产环境的情况.springboot中提供了 spring.profile.active的 ...
- 浅谈FFT(快速傅里叶变换)
前言 啊摸鱼真爽哈哈哈哈哈哈 这个假期努力多更几篇( 理解本算法需对一些< 常 用 >数学概念比较清楚,如复数.虚数.三角函数等(不会的自己查去(其实就是懒得写了(¬︿̫̿¬☆) 整理了一 ...
- 一些求和式的估算 & 杜教筛时间复杂度证明
本文内容概要: \(A=\sum\limits_{i=1}^n\dfrac1{\sqrt i}=1+\dfrac1{\sqrt2}+\cdots+\dfrac1{\sqrt n}\) \(O(\sqr ...
- 防火墙——firewalld
介绍 firewald是对于iptables的一个封装,可以让你更容易地管理iptables规则.firewalld是iptables前端控制器,用于实现持久地网络流量规则. 一.对比 firewal ...