正则re
1.简介
其实re在基本模块里已经介绍过,但是在爬虫中re是非常重要的,所以在这里再进行详细描述。
re在解析html内容时是效率最高的,但是也是最难的,一般来说,都是结合xpath和re使用,这样解析html文件会事半功倍
2.单个字符串的匹配
# -*-coding:utf8 -*- import re #本节匹配单个字符 #1.匹配某个字符串 # text="hello" # text2="ahello" #match只能从开头开始匹配 # ret=re.match('he',text) #调用group方法,就得得到匹配结果。如果没有匹配到,是None的话,调用group()会报错 # print(ret.group()) #2.点,匹配任意的字符 #可以匹配到空格,但是不能匹配到换行符 # text='hello' # text2='\n' # ret=re.match(".",text) # ret=re.match(".",text2) # print(ret.group()) #3.\d 匹配任意的数字(0-9) # text='12' # ret=re.match("\d",text) # print(ret.group()) #4.\D 匹配任意的非数字 # text='+' # ret=re.match("\D",text) # print(ret.group()) #5.\s,匹配空白字符(\n,\t,\r,空格) # text=' asd' # ret=re.match("\s",text) # print(ret.group()) #6.\w,匹配字母,数字及下划线 # text='_' # ret=re.match("\w",text) # print(ret.group()) #7.\W,匹配非字母数字下划线 # text='+()*&^%' # ret=re.match("\W+",text) # print(ret.group()) #8.[]组合的方式,只要满足中括号中的字符,就可以匹配 # text='-0731-888888' #\可以转义有特殊含义的字符 # ret=re.match("[\d\-]+",text) # print(ret.group()) #group()和groups()的区别 ''' groups()以元组返回所有分组匹配的字符。 group(0)代表整个匹配结果,group(1)列出第一个分组匹配部分,group(2)列出第二个分组匹配部分。 如果没有分组,则调用group(),则可以显示匹配内容。没有分组,使用groups会匹配到空 ''' #8.1 中括号的形式代替\d # text='0731-888888' # ret=re.match("[0-9]+",text) # print(ret.group()) #8.2 中括号的形式代替\D # text='0731-888888' # ret=re.match("[^0-9]",text) # print(ret.group()) #8.3 中括号的形式代替\w # text='s0731-888888' # ret=re.match("[a-zA-Z_]",text) # print(ret.group()) #8.4 中括号的形式代替\W # text='PW31-888888' # ret=re.match("[^a-zA-Z_]",text) # print(ret.group())
3.匹配多个字符
# -*-coding:utf8 -*- import re #9. * 可以匹配0或任意多个字符 # text=' 0731' # ret=re.match('\d*',text) # print(ret.group()) #10. + 匹配一个或者多个字符(最少要有一个字符匹配上) # text='abcd' # ret=re.match('\w+',text) # print(ret.group()) #11. ? 匹配一个或者0个字符(要么没有,要么只有一个) # text='+abcd' # ret=re.match('\w?',text) # print(ret.group()) #12. {m},匹配m个字符 # text='abcd' # ret=re.match('\w{2}',text) # print(ret.group()) #13. {m,n},匹配m-n个字符 # text='abcd' # ret=re.match('\w{1,5}',text) # print(ret.group())
4.多个小案例
# -*-coding:utf8 -*- import re #1.验证手机号码:手机号码的规则是以1开头,第二位可以是34587,后面9位随意 # text='18570662061' # ret=re.match("1[34578]\d{9}",text) # print(ret.group()) #2.验证邮箱 # text='hynever123_@qq.com' # ret=re.match('\w+@[a-z0-9]+\.com',text) # print(ret.group()) #3.验证URL:URL的规则是前面是http或者是https或者是ftp然后再加上一个冒号,再加上一个斜杠,再后面 # 就是可以出现任意非空白字符了 # text='http://www.baidu.com/s?wd=python' # ret=re.match('(http|https|ftp)://[^\s]+',text) # print(ret.group()) #4.验证身份证 text='45621524214712387X' ret=re.match('\d{17}[\dxX]',text) print(ret.group())
5.开始、结束、或语法
# -*-coding:utf8 -*- import re #1.^(脱字号)表示匹配以什么开头 # text='hello world' # ret=re.search('^h',text) # print(ret.group()) #放在中括号[]中,表示取反 #2. $ 表示以匹配以什么结尾 # text='xxx@163.comasdasdas' # ret=re.match('\w+@163.com$',text) # print(ret.group()) #3. | 匹配多个字符串或者表达式 # text='httpsdasda' # ret=re.match('(ftp|http|https)',text) # print(ret.group()) #4.贪婪模式与非贪婪模式(默认采用的都是贪婪模式) # text='0123456' # ret=re.match('\d+',text) # print(ret.group()) #想用非贪婪模式,在匹配条件后面加一个问号.这样匹配的就是满足的最小条件 # text='0123456' # ret=re.match('\d+?',text) # print(ret.group()) # text='<h1>标题</h1>' # ret=re.match('<.+>',text) # ret=re.match('<.+?>',text) # print(ret.group()) #案例:匹配0-100之间的数字 #可以出现的:0,1,2,3,4,... #不可以出现的:09,101 (09这种数字写法是不合法的,第一个不能为0) #有三种情况:1,99,100 text=' ret=re.match('[1-9]\d?$|100$',text) print(ret.group())
6.转义字符和原生字符串
# -*-coding:utf8 -*- import re #转义字符和原生字符串 ''' 在正在表达式中,有些字符是有特殊意义的字符。因此如果想要匹配这些字符,那么就必须使用反斜杠进行转义。 比如$代表的是以...结尾,那么就必须使用\$ ''' # text='apple price is $499' # ret=re.search('\$\d+',text) # print(ret.group()) #原生字符串 ''' 在正则表达式中,\是专门用来做转义的。在python中\也是用来做转义的。因此如果想要在普通的字符串中 匹配出\,那么要给出4个\。 ''' # text='\c' #在python语言层面,'\\\\c'经过转义,成了'\\c',然后扔给正则去匹配,又经过转义成了'\c' # ret=re.search('\\\\c',text) # print(ret.group()) #在python语言层面,还有一种转义方式,r'\c',这是python自带的转义,r=raw表示原生的意思 #推荐使用这种写法,以免太过复杂 # text='\c' # ret=re.search(r'\\c',text) # print(ret.group()) # print('\n') # print(r'\n')
7.group分组
# -*-coding:utf8 -*- import re #re模块常用函数 #match:从开始的位置进行匹配。如果开始的位置没有匹配到,那就直接失败了 #search:在字符串中找满足条件的字符。如果找到,就返回。说白了,就是只会找到第一个满足条件的 #分组 ''' 在正则表达式中,可以通过对过滤到的字符串进行分组。分组使用圆括号的方式 ''' text="apple's price is $99,orange's price is $10" ret=re.search('.*(\$\d+).*(\$\d+)',text) #可以打印每个分组里面的内容 # print(ret.group(2)) # print(ret.group(1,2)) #拿到所有的子分组都拿到 print(ret.groups()) #整个正则表达式是一个大的分组,直接用group()或group(0)拿到 # print(ret.group()) # print(ret.group(0))
8.常用函数
# -*-coding:utf8 -*- import re # findall # 找出所有满足条件的,返回的是一个列表 # text="apple's price is $99,orange's price is $10" # ret=re.findall('\$\d+',text) # print(ret) # sub # 用来替换字符串。 # text="apple's price is $99,orange's price is $10" # sub要先传一个匹配条件,再传要修改成的内容,然后传要进行匹配的字符串,再传入count:要修改几个 # count不传个数,则默认全部修改 # ret=re.sub('\$\d+','0',text) # ret=re.sub('\$\d+','0',text,1) # print(ret) # html = """ # <p>服务端研发工程师<br><br>职责:<br><br>负责服务端后台功能的研发,包括Web服务、数据分析统计、运营管理系统。<br><br>要求:<br><br>1. 熟练使用Python及其常用类库<br>2. 熟练使用SQL语言<br>3. 熟悉Linux和MySQL的使用<br>4. 熟悉常用网络协议,譬如HTTP<br><br>加分项:<br><br>1. 热爱技术<br>2. 熟悉Android系统<br>3. 熟悉Java语言</p> # """ # ret = re.sub('<.+?>', '', html) # print(ret) #split #使用正则表达式来分隔字符串。用什么进行分隔,返回的是一个列表。 # text='hello &world ni hao' # ret=re.split(' ',text) # ret=re.split(' |&',text) # ret=re.split('[^a-zA-Z]',text) # print(ret) #compile #对于一些经常要用到的正则表达式,可以使用compile进行编译,后期再使用的时候可以直接拿过来用, #执行效率会更快。而且compile还可以指定flag=re.VERBOSE,在写正则表达式的时候可以做好注释 # text='the number is 20.50' #先写匹配条件。这个正则匹配条件是存放在内存当中,如果是高并发场景,可以用这个 # r=re.compile('\d+\.?\d*') # ret=re.search(r,text) # print(ret.group()) #re.VERBOSE 注释功能,省的每次看正则匹配要花时间,直接把注释给上 # text='the number is 20.50' # r=re.compile(r""" # \d+ #小数点前面的数字 # \.? #小数点本身 # \d* #小数点后面的数字 # """,re.VERBOSE) # ret=re.search(r,text) # print(ret.group())
9.古诗文网爬虫实战
# -*-coding:utf8 -*- import re import requests def parse_page(url): headers={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', } response=requests.get(url,headers=headers) text=response.text # . 不能匹配\n 如果想要它匹配\n等字符,要加上flags=re.DOTALL #re.S=re.DOTALL titles=re.findall(r'<div\sclass="cont">.*?<b>(.*?)</b>',text,re.S) dynasties=re.findall(r'<p class="source">.*?<a.*?>(.*?)</a>',text,re.DOTALL) authors=re.findall(r'<p class="source">.*?<a.*?>.*?<a.*?>(.*?)</a>',text,re.DOTALL) content_tags=re.findall(r'<div class="contson".*?>(.*?)</div>',text,re.DOTALL) contents=[] for content in content_tags: x=re.sub(r'<.*?>','',content) contents.append(x.strip()) poems = [] for value in zip(titles,dynasties,authors,contents): title,dynasty,author,content=value poem={ 'title':title, 'dynasty':dynasty, 'author':author, 'content':content } poems.append(poem) print(poems) #zip函数 pass def main(): url='https://www.gushiwen.org/default_1.aspx' parse_page(url) if __name__ == '__main__': main()
10.糗事百科爬虫实战
# -*-coding:utf8 -*- import re import requests headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', } def parse_page(url): response =requests.get(url,headers=headers) text=response.text authors=re.findall(r'<div class="author clearfix">.*?<h2>(.*?)</h2>',text,re.S) authors=[author.strip() for author in authors] content_tags=re.findall(r'<div class="content">(.*?)</span>',text,re.S) contents=[] for content in content_tags: x=re.sub(r'<.*?>','',content) x=x.replace('\t','') x=x.replace('\n','') contents.append(x) poems=[] for value in zip(authors,contents): author,content=value poem={ 'author':author, 'content':content } poems.append(poem) return poems def main(): urls=['https://www.qiushibaike.com/text/page/{}/'.format(i) for i in range(10)] duanzi=[] for url in urls: poems=parse_page(url) duanzi.extend(poems) return duanzi if __name__ == '__main__': res=main() print(res) print(len(res))
正则re的更多相关文章
- Javascript正则对象方法与字符串正则方法总结
正则对象 var reg = new Regexp('abc','gi') var reg = /abc/ig 正则方法 test方法(测试某个字符串是否匹配) var str = 'abc123'; ...
- C#-正则,常用几种数据解析-端午快乐
在等待几个小时就是端午节了,这里预祝各位节日快乐. 这里分享的是几个在C#中常用的正则解析数据写法,其实就是Regex类,至于正则的匹配格式,请仔细阅读正则的api文档,此处不具体说明,谢谢. 开始吧 ...
- Javascript 中 with 的替代方案和String 中的正则方法
这几天在升级自己的MVVM 框架,遇到很多小问题,就在这里统一解决了. with 语法 在代码中,要执行这么一个函数 function computeExpression(exp, scope) { ...
- JavaScript与PHP中正则
一.JavaScript 有个在线调试正则的工具,点击查看工具.下面的所有示例代码,都可以在codepen上查看到. 1.创建正则表达式 var re = /ab+c/; //方式一 正则表达式字面量 ...
- Java正则速成秘籍(一)之招式篇
导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...
- Java正则速成秘籍(二)之心法篇
导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...
- Java正则速成秘籍(三)之见招拆招篇
导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...
- python浅谈正则的常用方法
python浅谈正则的常用方法覆盖范围70%以上 上一次很多朋友写文字屏蔽说到要用正则表达,其实不是我不想用(我正则用得不是很多,看过我之前爬虫的都知道,我直接用BeautifulSoup的网页标签去 ...
- [Python基础知识]正则
import re str4 = r"^http://qy.chinahr.com/cvm/preview\?cvid=\w{24,25}&from=sou>id=\w{ ...
- iOS中使用正则
一.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...
随机推荐
- 如何使用 Lucene 做网站高亮搜索功能?
现在基本上所有网站都支持搜索功能,现在搜索的工具有很多,比如Solr.Elasticsearch,它们都是基于 Lucene 实现的,各有各的使用场景.Lucene 比较灵活,中小型项目中使用的比较多 ...
- Java Spring Boot VS .NetCore (三)Ioc容器处理
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- EF执行SQL返回动态类型
using System; using System.Data.Common; using System.Data.Entity.Core.Objects; using System.Data.Ent ...
- java实现哈夫曼编码
java实现哈夫曼编码 哈夫曼树 既然是学习哈夫曼编码,我们首先需要知道什么是哈夫曼树:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫 ...
- BZOJ-9-3295: [Cqoi2011]动态逆序对
题意:N个数的排列,M次操作,每次求当前的逆序对数量并删掉一个数 思路 :动态说的很到位.hiahia ... 最初一直没想明白为什么 大佬的cdq 中统计了两次. 先定义 给出的删除的点的 t 值依 ...
- django——视图层
1. 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. ...
- 使用mybatis assembly插件打成tar包,在linux系统中运行服务
使用mybatis assembly插件打成tar包,在linux系统中运行服务 assembly插件插件地址: 链接:https://pan.baidu.com/s/1i6bWPxF 密码:gad5 ...
- rsyslog 移植与配置方案介绍
rsyslog介绍 rsyslog是一个 syslogd 的多线程增强版.它提供高性能.极好的安全功能和模块化设计.虽然它基于常规的 syslogd,但 rsyslog 已经演变成了一个强大的工具,可 ...
- 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第5章编程练习3
#include <iostream>using namespace std;int main(){ double count=0; long double cleo=100; long ...
- 文件上传(xls)
function UploadFile(){ var filewj =document.getElementById("filewj").files[0]; //input Id ...