Python爬虫自学之第(④)篇——强大的正则表达式,re模块

题外话:

《Pi Network 免费挖矿国外热门项目 一个π币大约值3元到10元》相信过去BTC的人,信不信未来的PI,了解一下,唯一一个高度与之持平的项目

 

如果把BeautifulSopu比喻成通过线索一步步接近目标的侦探的话,那么正则表达式就是牛逼哄哄的“天眼系统”,只要提供一些目标的特征,无论搜索范围多大,只要存在那么一两个符合特征的目标,全都会被它直接逮住。

 

特性

牛逼王

  • BS的爸爸,我告诉你个秘密,其实BeautifulSoup也是用正则实现的,而且它find_all的参数里还能接收正则呢
  • 信息精确定位,BeautifulSoup用的是节点定位,可能会出现多个符合条件的节点(却没有目标信息);正则是直接针对目标信息,以字符为单位匹配,一次筛选出正确结果(前提是写好正则)
  • 能获取信息的部分,有时候完整的信息不是你想要的,你只想取它的某一部分,正则能搞定,BS只能先获取完整信息再分离。
  • 用途大着呢,不要以为正则只能爬虫,前后端都少不了正则,你填个信息判断是否合法这都是正则,总之学到赚到

劝退大王+

这么强大的方法是不是看到都心动了,不过强大是有代价的,较难上手很难精通这两根大棒一下子锤走了不少初学者。当时学的我是这样的:图片描述

  • 抽象&可读性差。为了逮住某个目标,你可能要写一条长长的,看到自己都头晕的正则表达式,看上去就像乱码一样。举个栗子,如果你要匹配一个ip地址,正则表达式会是这样

    匹配ip地址:((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)) ——真·乱码
  • 编写时出错率高,新手很难一次写对,需要不停地修改几次十几次才能pass(大脑在颤抖)
  • 难于优化,优化好的正则能提高匹配速度,然而你这新手还想优化,能匹配对就很不错了(正则暗中偷笑)

如果有足够的自信和毅力不被正则击倒,那就来吧。(屁,学正则还不是迟早的事!)

re 模块

python 自带模块,直接导入即可。有匹配,替换等方法。
思考了许久后笔者觉得还是先讲表达式(规则)好,因为某些方法的理解是要了解表达式的。
下文的规则是完全版的,花了很久写成,分享给读者,顺便当成自己的网上笔记。

如果你学正则只是单单用来爬虫的话,你只要熟悉“字符匹配”,“分组&或&转义”,“预定字符集”,“数量词”,“非贪婪模式”和(?:)取消分组,了解(或干脆不学)“边界匹配”,“特殊构造”就行了。

如果你觉得正则是你未来工作的刚需的话,推荐熟悉所有规则。

匹配规则(pattern)

规则其实是一个原字符串如r'表达式'/r"表达式",较正式的叫法是模式字符串。最后再说一句,匹配以单个字符为单位(除括号能把多个字符打包成分组(整体)来匹配


表达式本质是字符串,不要单引(双引)号里套单引(双引)号,会出错。

字符匹配

  • 任一字符(空格也算)——就是匹配这个字符,某些字符因为在正则中有特殊用途需前加反斜杠转义如 [ { . | ( ) ^ * + ? $
  • .——英文句号,匹配除换行符\n外的任意单个字符
  • []——匹配中括号里的任一字符,与-结合还能表示范围内的任一字符,中括号内的字符除\外会自动转义,还有小心多个中括号嵌套错误
  • [^]——中括号最前面加^,与[ ]反义,匹配一个不在中括号里的字符,也可以用横杠-
r'[abcd]'#匹配一个a或b或c或d
r'[0-9]'#匹配一个0至9的数,-的作用域是左右各一个字符
r'[a-z]'  r'[A-Z]'#分别匹配a到z或A到Z的一个字母
r'[12-89]'#注意因为是单字符匹配,匹配的是1,2到8的数,9(即1到9的一个数),不是12到89的数
r'[{.|()^*+?$\\]'#匹配 { . | ( ) ^ * + ? $ \中任一个,\要转义
r'[^a-zA-Z]'#匹配一个不是字母的字符

分组&或&转义

  • ()——括号,表达式分组(第n组,n=1,2,3....99,从左往右数),并形成子表达式
  • (?P<name>)——拥有括号的功能,但能为该分组再指定一个自定名字
  • (?P=name)——引用分配过名字的分组,但没有分组功能
  • |——或,左右规则任意匹配一个,从左往右尝试匹配,一旦成功就跳过后面的规则。|没被包在括号中间的话它的作用域是整个表达式,被包的话作用域在括号内
  • \——反斜杠,后接功能字有符转义功能,后接数字(1到99)有引用分组的功能,后接某些字母又有特殊功能
r'abc|def|ghi'#匹配abc或def或ghi
r'ma(?:k|d)e'#匹配make或made
r'(abc)def\1'#相当于r'(abc)defabc',匹配abcdefabc
r'(?P<ok>abc)f(?P=ok)'#为(abc)子组分配了“ok”的名字,然后再引用,匹配abcfabc

预定字符集

  • \d——匹配任一个数字(0~9)
  • \D——匹配一个非数字字符,与\d互补
  • \s——匹配一个空白字符,包括空格,\t,\n,\r,\n,\f,\v
  • \S——匹配一个非空白字符
  • \w——匹配一个单词字符。unicode下匹配各种语言的单个字符,单个数字,和下横线。ASCII下匹配单个英文字母,单个数字,和下横线
  • \W——匹配一个非单词字符
r'\w' #能匹配'物语&ものがたり'中的:物,语,も,の,が,た,り,汉语日语的单字,其他语言同理

数量词(接在字符或子组后)

  • {n}——作用于前一个字符或子表达式,匹配它重复n次
  • {min,max}——作用于前一个字符或子表达式,匹配它重复重复多少次min~max次,min和max可只写一个设置重复下限或上限,但逗号不能省,不写min时min默认为0
  • *——星号,作用于前一个字符或子表达式,匹配它零次或多次
  • +——作用于前一个字符或子表达式,匹配它至少一次
  • ?——作用于前一个字符或子表达式,匹配它零次或一次
r'z{3}'#匹配zzz
r'z{0,3}'#匹配z或zz或zzz
r'(?:abc){2}'#对子表达式匹配两次,匹配abcabc,(?:)是一个用法,不分组的意思,详看后面
#星号加号问号同理

非贪婪模式

  • 在数量词后接?,对前面的数量词开启非贪婪模式,意思就是在能匹配的前提下尽可能少的重复匹配
  • 正则默认开启贪婪模式
r'<.+>'#默认贪婪,对于'<abc><def>'能匹配到'<abc><def>'整条,因为.贪婪地把尖括号也匹配掉了
r'<.+?>'#非贪婪,对于'<abc><def>'能匹配到'<abc>'和'<def>'

边界匹配

  • ^——放在表达式的最前面,作用域是表达式,在多行模式中,在每一行匹配字符串开头(多行模式要手动开启,否则和\A没什么区别)
  • $——放在表达式的最后面,作用域是表达式,在多行模式中,在每一行匹配字符串末尾(多行模式要手动开启,否则和\Z没什么区别)
  • \A——放在表达式的最前面,作用域是表达式,匹配字符串开头,不能多行匹配
  • \Z——放在表达式的最后面,作用域是表达式,匹配字符串末尾,不能多行匹配
  • \b——不匹配字符,只匹配一个边界,匹配\w和\W或\W和\w的边界(单词字符和非单词字符的边界)
  • \B——不匹配字符,只匹配一个边界,与\b相反,匹配\w和\w或\W和\W的边界
r'^abc|^def'#匹配abc开头或def开头,开启了多行模式时,对字符串'abcd\ndefh'能匹配出abc,def两个
r'abc$|def$'#匹配abc结尾或def结尾,开启了多行模式时,对字符串'0abc\n0def'能匹配出abc,def两个
r'\Aabc'#匹配abc开头,因为不能多行匹配,就算开启多行模式,对字符串'abcd\nabcd'只能匹配到前面的abc
#\Z同理
r'\w\b\W'#匹配“单词字符+非单词字符”的结构如'a!','1%'
#\B同理

特殊构造(不作为分组,不被findall捕获)

    • (?:)——取消括号的分组功能,使其不会被findall方法捕获
    • (?#)——#后写注释内容,整个(?#)会被忽略
    • A(?=)——A之后的字符串需要匹配括号里的表达式A才会被匹配,一定用在表达式的最后(A是表达式,(?=)内的表达式不会被匹配捕捉,下同)
    • A(?!)——A之后的字符串需要不匹配括号里的表达式A才会被匹配,一定用在表达式的最后
    • (?<=)A——A之前的字符串需要匹配括号里的表达式A才会被匹配,一定用在表达式的最前,括号内的表达式需固定长度不能使用除{n}外的数量词
    • (?<!)A——A之前的字符串需要不匹配括号里的表达式A才会被匹配,一定用在表达式的最前,括号内的表达式需固定长度不能使用除{n}外的数量词
r'(ab(?=cde))'#匹配后面是bcd的ab
r'a(?!\d+)'#匹配后面不跟一串数字的a,后括号可用所有数量词
r'(?<=abc)de'#匹配前面是abc的de
r'(?<!\d{3})a'#匹配前面不是三个数字的a,前括号可以用{n}但是不能用不定量的数量词
  •  (?iLmsux)——放在表达式最前面,为所在的表达式设置模式,”i”, “L”, “m”, “s”, “u”, “x”,它们不匹配任何字串,对应python中re模块当中的(re.I, re.L, re.M, re.S, re.U, re.X)的6种模式,下面flag参数讲
r'(?i)abc'#“i”对应re.I,忽略大小写模式,能匹配Abc,ABC,abc等

方法&参数

相比于繁杂的规则,方法则要简单多了,常用的就这几个:

  • re.search(pattern,string,flags=0),返回第一个匹配的match对象(内含匹配字符串的信息)
  • re.findall(pattern,string,flags=0),返回所有匹配分组的字符串组成的列表,没设置分组相当于整个表达式就是一个分组
  • #如果表达式有多个分组,会返回复杂的列表,因此findall中的表达式通常只有一个分组
  • re.finditer(pattern,string,flags=0),同findall功能,但是返回的是迭代器

#分组为(abc),findall只捕捉被数字包起来的abc返回列表['abc','abc']
re.findall(r'\d+(abc)\d+','1abc1,2abc2')
#整个表达式匹配abab加一个两位数,(?:)取消了ab的分组,findall只捕捉abab加一个数,返回列表['abab1','abab2']
re.findall(r'((?:ab){2}\d)\d','abab11,abab22')
  • pattern = re.compile(pattern,flags=0),把规则打包返回(如多次使用该规则),相当与pattern和flag的合体,当成pattern使用可免去设置flags
  • re.sub(pattern,repl,string,count=0,flags)把匹配到的部分用指定字符串repl替换,count设置替换次数,默认为零替换所有

参数:

  • pattern:接收模式字符串,即表达式,也可以接收打包的规则
  • string:接收待匹配字符串,如html文档
  • flags:模式(标签),接受以下模式,多个模式用“|”分开如 flags=re.I|re.M

    • re.I = re.IGNORECASE   忽略大小写
    • re.L = re.LOCALE   支持当前语言,为了支持多语言版本的字符集使用环境
    • re.U = re.UNICODE   使用w,W,b,B这些元字符时将按照UNICODE定义的属性
    • re.M = re.MULTILINE   开启多行模式
    • re.S = re.DOTALL   使.能匹配换行符\n
    • re.X = re.VERBOSE   可以忽略正则表达式中的空白和#号的注释,不匹配空格和#注释
    • re.A  开启ASCII模式

match对象方法

列出常用方法,下面的match是对象

  • match.group(id/name)id是分组序号(1~99),name是分组的自定名字,返回指定分组的字符串;不传参数数是返回整条匹配字符串
  • match.start(id/name),match.end(id/name),match.span(id/name),分别返回指定分组字符串在整个字符串中的开始位置,结束位置,范围。


正则慢慢学就行,正则的使用后面会有实例让大家熟悉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/413291.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫自学之第(⑤)篇——爬取某宝商品信息

题外话&#xff1a; 《Pi Network 免费挖矿国外热门项目 一个π币大约值3元到10元》相信过去BTC的人&#xff0c;信不信未来的PI&#xff0c;了解一下&#xff0c;唯一一个高度与之持平的项目 能看到这里说明快进入动态网页爬取了&#xff0c;在这之前还有一两个知识点要了解&…

Vue通信、传值的多种方式,详解

Vue通信、传值的多种方式&#xff0c;详解 转自&#xff1a;https://blog.csdn.net/qq_35430000/article/details/79291287 一、通过路由带参数进行传值 ①两个组件 A和B,A组件通过query把orderId传递给B组件&#xff08;触发事件可以是点击事件、钩子函数等&#xff09; this.…

python 文件读写(追加、覆盖)

很明了的一个常用参数图标&#xff1a; 更像细的一个参数说明&#xff1a; 由于文件读写时都有可能产生IOError&#xff0c;一旦出错&#xff0c;后面的f.close()就不会调用。所以&#xff0c;为了保证无论是否出错都能正确地关闭文件&#xff0c;我们可以使用try ... finally来…

前端知识点总结

1、DOM结构 —— 两个节点之间可能存在哪些关系以及如何在节点之间任意移动。(通俗易懂的来讲讲DOM、两个节点之间可能存在哪些关系以及如何在节点之间任意移动) DOM: Document Object Module, 文档对象模型。 节点的关系:父(parent)、子(child)和同胞(sibling)等节…

Python爬虫自学之第(①)篇——爬虫伪装和反“反爬”

有些网站是防爬虫的。其实事实是&#xff0c;凡是有一定规模的网站&#xff0c;大公司的网站&#xff0c;或是盈利性质比较强的网站&#xff0c;都是有高级的防爬措施的。总的来说有两种反爬策略&#xff0c;要么验证身份&#xff0c;把虫子踩死在门口&#xff1b;要么在网站植…

Spring 事务相关及@Transactional的使用建议

使用步骤&#xff1a; 步骤一、在spring配置文件中引入<tx:>命名空间<beans xmlns"http://www.springframework.org/schema/beans" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns:tx"http://www.springframework.org/schema/…

谷歌浏览器安装Vue Devtools插件(国内的谷歌浏览器如何安装插件)

分享给大家一个谷歌插件网站&#xff0c;适合国内谷歌浏览器无法安装插件的问题&#xff0c;你懂的 点击这里下载Vue.js Devtools插件&#xff0c; 喜欢的可以收藏这个插件资源网站&#xff0c;分享给大家 第一步&#xff1a;下载后解压获得CRX文件&#xff0c;如下图 第二步…

MySQL操作权限整理

用户权限管理主要有以下作用&#xff1a; 1. 可以限制用户访问哪些库、哪些表 2. 可以限制用户对哪些表执行SELECT、CREATE、DELETE、DELETE、ALTER等操作 3. 可以限制用户登录的IP或域名 4. 可以限制用户自己的权限是否可以授权给别的用户 一、用户授权 mysql> grant a…

vue报错 TypeError: merge is not a function

利用ncu -u升级去年的vue项目package.json里的所有依赖&#xff0c;目的是想增删改它去做另一个项目&#xff0c; 却发生了这样一个错误&#xff1a;&#xff08;如下&#xff09; 查找问题原因&#xff1a; 这是webpack配置中区分环境配置文件中的插件webpack-merge的报错&a…

Invalid options object. Copy Plugin has been initialized using an options object that does not match

报错&#xff1a; 报错文件和代码&#xff1a;查看了官网也没有看出所以然&#xff0c;最后在npm官网上找打了原因 错误配置&#xff1a; 怎么看都没有错误 最后参看一下这个npn官网找打了原因&#xff0c;地址&#xff1a;https://www.npmjs.com/package/copy-webpack-plugin …

后台返回数据打印是[object object]的,报错:SyntaxError: JSON.parse: expected property name or ‘}‘ at line 1 column

今天基于这个问题纠结了一下午&#xff0c;导致这个问题的坑也是挺深的&#xff0c;查找问题最好是从这条数据的存储开始查找 问题1&#xff1a;先确定后台接收数据后存储到数据库里有没有自动转义特殊字符&#xff0c;比如 原始数据是&#xff1a;[{"user_id":20,…

Java开发框架和中间件面试题(4)

27.如何自定义Spring Boot Starter&#xff1f; 1.实现功能 2.添加Properties 3.添加AutoConfiguration 4.添加spring.factory 在META INF下创建spring.factory文件 6.install 28.为什么需要spring boot maven plugin? spring boot maven plugin 提供了一些像jar一样打包…

第二周每周例行报告

1.本周PSP 类型任务开始时间结束时间间隔时间净时间准备工作复习C#&#xff0c;看书2018.9.19 17&#xff1a;032018.9.19 18&#xff1a;17 0min74min编程编写功能一2018.9.20 18&#xff1a;072018.9.20 22&#xff1a;4323min253min编程完善修改功能一2018.9.21…

poj 1083 Moving Tables

题目 两种做法&#xff0c;开始用贪心做的&#xff0c;有种情况没考虑到&#xff0c;结果排序错了。 这个例子&#xff0c;感觉上有三个交点&#xff0c;以为是30&#xff0c;其实是20. 贪心代码&#xff1a; #include <iostream> #include <cstdio> #include <…

oracle parallel_index hint在非分区表的生效

之前没特别注意&#xff0c;在有些场景下希望使用并行索引扫描的时候&#xff0c;发现parallel_index hint并没有生效&#xff0c;于是抽空看了下文档&#xff1a;The PARALLEL_INDEX hint instructs the optimizer to use the specified number of concurrent servers to para…

eclipse 界面设置与字体更改

目录 eclipse 界面设置与字体更改更改界面颜色&#xff08;Windows&#xff09;windows下全设置窗口颜色eclipse下设置Console窗口颜色设置字体与字号安装Courier New字体设置字体eclipse 界面设置与字体更改 每天换一个新的环境总是要重新设置eclipse的各种配置&#xff0c;最…

HTTP和HTTPS协议及工作原理分析

HTTP协议概念 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff0c;属于应用层&#xff09;是用于从服务器传输超内容到本地浏览器的传送协议。是一个无状态的协议 想了解http&#xff0c;就需要了解TCP&#xff0c;IP协议。因为http是基…

前端兼容性问题

一、CSS 1、浏览器的兼容性问题-CSS 盒子模型(Box Model) 一旦为页面设置了恰当的 DTD&#xff0c;大多数浏览器都会按照上面的图示来呈现内容。然而 IE 5 和 6 的呈现却是不正确的。根据 W3C 的规范&#xff0c;元素内容占据的空间是由 width 属性设置的&#xff0c;而内容周…

索引原理及几种索引类型区别

在关系数据库中&#xff0c;索引是一种单独的、物理的对数据库表中的一列或多列的值进行排序的一种存储结构&#xff0c; 它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录&#xff0c;可以根据目录中的页码…

Android Studio Intent使用(显式、隐式)

https://blog.csdn.net/u012005313/article/details/47006689 使用Intent能够使程序在不同活动中跳转&#xff0c;意及能够使用不同界面。Intent用法分为显示和隐式 Intent概念&#xff1a;Intent是Android程序中各组件之间进行交互的一种重要方式&#xff0c;不仅可以指明当前…