现在

你已经会使用 python 模拟浏览器

进行一些 Http 的请求了

那么请求完之后

服务器返回给我们一堆源代码

我们可不是啥都要的啊

我们是有原则的

我们想要的东西

怎么能一股脑的啥都往自己兜里塞呢?

使不得

使不得

所以

在服务器返回给我们的源码之中

我们要过滤

拿到我们想要的就好

其它就丢一旁

那么

我们就需要学会怎么使用

正则表达式

 

通过它

我们才能过滤出我们想要的内容

...

接下来就是

学习 python 的正确姿势

真香警告

这篇文章不适合急性子的人看,要不然会把手机砸了的!但是,如果你能看完,那么正则表达式对你来说,算个 p 的难度啊?

其实

正则表达式不仅仅适用于 python

很多编程语言

很多地方都会使用到正则

试想一下

如何从下面这段字符串中快速检索所有的数字出来呢?

zui12shu234ai45der6en7sh88ixia7898os0huaib

简单来说

正则表达式就是定义一些特殊的符号

来匹配不同的字符

比如

\d

就可以代表

一个数字,等价于 0-9 的任意一个

那么你肯定想知道

其它的特殊符号表示的啥意思吧?

就不告诉你

本篇完

再见

这是各种符号的解释

字符 描述
\ 将下一个字符标记为一个特殊字符(File Format Escape,清单见本表)、或一个原义字符(Identity Escape,有^$()*+?.[\{|共计12个)、或一个向后引用(backreferences)、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。序列“\\”匹配“\”而“\(”则匹配“(”。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”、“zo”以及“zoo”。*等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 非贪心量化(Non-greedy quantifiers):当该字符紧跟在任何一个其他重复修饰符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
. 匹配除“\r”“\n”之外的任何单个字符。要匹配包括“\r”“\n”在内的任何字符,请使用像“(.|\r|\n)”的模式。
(pattern) 匹配pattern并获取这一匹配的子字符串。该子字符串用于向后引用。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。可带数量后缀。
(?:pattern) 匹配pattern但不获取匹配的子字符串(shy groups),也就是说这是一个非获取匹配,不存储匹配的子字符串用于向后引用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?<=pattern) 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern) 反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。
x|y 没有包围在()里,其范围是整个正则表达式。例如,“z|food”能匹配“z”或“food”。“(?:z|f)ood”则匹配“zood”或“food”。
[xyz] 字符集合(character class)。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。特殊字符仅有反斜线\保持特殊含义,用于转义字符。其它特殊字符如星号、加号、各种括号等均作为普通字符。脱字符^如果出现在首位则表示负值字符集合;如果出现在字符串中间就仅作为普通字符。连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位(或末尾)则仅作为普通字符。右方括号应转义出现,也可以作为首位字符出现。
[^xyz] 排除型字符集合(negated character classes)。匹配未列出的任意字符。例如,“[^abc]”可以匹配“plain”中的“plain”。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z] 排除型的字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
[:name:] 增加命名字符类(named character class)[注 1]中的字符到表达式。只能用于方括号表达式
[=elt=] 增加当前locale下排序(collate)等价于字符“elt”的元素。例如,[=a=]可能会增加ä、á、à、ă、ắ、ằ、ẵ、ẳ、â、ấ、ầ、ẫ、ẩ、ǎ、å、ǻ、ä、ǟ、ã、ȧ、ǡ、ą、ā、ả、ȁ、ȃ、ạ、ặ、ậ、ḁ、ⱥ、ᶏ、ɐ、ɑ 。只能用于方括号表达式。
[.elt.] 增加排序元素(collation element)elt到表达式中。这是因为某些排序元素由多个字符组成。例如,29个字母表的西班牙语, "CH"作为单个字母排在字母C之后,因此会产生如此排序“cinco, credo, chispa”。只能用于方括号表达式。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。x的值必须为A-Za-z之一。否则,将c视为一个原义的“c”字符。控制字符的值等于x的值最低5比特(即对3210进制的余数)。例如,\cM匹配一个Control-M或回车符。\ca等效于\u0001, \cb等效于\u0002, 等等...
\d 匹配一个数字字符。等价于[0-9]。注意Unicode正则表达式会匹配全角数字字符。
\D 匹配一个非数字字符。等价于[^0-9]。
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。注意Unicode正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09和\cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。注意Unicode正则表达式会匹配中文字符。
\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xnn 十六进制转义字符序列。匹配两个十六进制数字nn表示的字符。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。.
\num 向后引用(back-reference)一个子字符串(substring),该子字符串与正则表达式的第num个用括号围起来的捕捉群(capture group)子表达式(subexpression)匹配。其中num是从1开始的十进制正整数,其上限可能是9[注 2]、31[注 3]、99甚至无限[注 4]。例如:“(.)\1”匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm 3位八进制数字,标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
\nml 如果n为八进制数字(0-3),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\un Unicode转义字符序列。其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

(来自维基百科)

你能看到这里

也是

不知道你看懵逼了没?

反正我是不想看了

接下来

才是干货

小帅b就给你精简一下

通俗的把最常用的匹配告诉你

字符 描述
\d 代表任意数字,就是阿拉伯数字 0-9 这些玩意。
\D 大写的就是和小写的唱反调,\d 你代表的是任意数字是吧?那么我 \D 就代表不是数字的。
\w 代表字母,数字,下划线。也就是 a-z、A-Z、0-9、_。
\W 跟 \w 唱反调,代表不是字母,不是数字,不是下划线的。
\n 代表一个换行。
\r 代表一个回车。
\f 代表换页。
\t 代表一个 Tab 。
\s 代表所有的空白字符,也就是上面这个:\n、\r、\t、\f。
\S

跟 \s 唱反调,代表所有不是空白的字符。

\A 代表字符串的开始。
\Z 代表字符串的结束。
^ 匹配字符串开始的位置。
$ 匹配字符创结束的位置。
. 代表所有的单个字符,除了 \n \r
[...] 代表在 [] 范围内的字符,比如 [a-z] 就代表 a到z的字母
[^...] 跟 [...] 唱反调,代表不在 [] 范围内的字符
{n} 匹配在 {n} 前面的东西,比如: o{2} 不能匹配 Bob 中的 o ,但是能匹配 food 中的两个o。
{n,m} 匹配在 {n,m} 前面的东西,比如:o{1,3} 将匹配“fooooood”中的前三个o。
{n,} 匹配在 {n,} 前面的东西,比如:o{2,} 不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。
* 和 {0,} 一个样,匹配 * 前面的 0 次或多次。 比如 zo* 能匹配“z”、“zo”以及“zoo”。
+ 和{1,} 一个样,匹配 + 前面 1 次或多次。 比如 zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。
和{0,1} 一个样,匹配 ?前面 0 次或 1 次。
a|b 匹配 a 或者 b。
() 匹配括号里面的内容。

ok

知道了这些之后

我们怎么用 python 来进行判断呢?

那就要使用到 python 的库了

它就是

re

 

接下来我们就来使用 re 模块

对其常用的方法

来使用正则表达式

re.match

使用这个方法

主要传入两个参数

第一个就是我们的匹配规则

第二个就是需要被过滤的内容

例如

我们想要从这

Xiaoshuaib has 100 bananas

拿到一个数字

那么我们就可以这样

import re

content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.*(\d+)\s.*s$',content)
print(res.group())

 

通过我们刚刚说的匹配符号

可以定义出相应的匹配规则

在这里我们将我们需要的目标内容用 () 括起来

此刻我们获得结果是

0

那么如果我们想要 100 这个数字呢?

可以这样

import re

content = 'Xiaoshuaib has 100 bananas'
res = re.match('^Xi.*?(\d+)\s.*s$',content)
print(res.group())

看出区别了么

第二段代码我们多了一个 ?符号

在这里呢

涉及到两个概念

一个是

贪婪匹配

另一个是

非贪婪匹配

所谓贪婪匹配

就是我们的第一段代码

一个数一个数都要去匹配

而非贪婪呢

我们是直接把 100 给匹配出来了

刚刚我们用到的

.*?

是我们在匹配过程中最常使用到的

表示的就是匹配任意字符

但是

.*?的 . 代表所有的单个字符,除了 \n \r

如果我们的字符串有换行了

怎么办呢?

比如这样

content = """Xiaoshuaib has 100 
bananas"""

那么我们就需要用到 re 的匹配模式了

说来也简单

直接用 re.S 就可以了

import re

content = """Xiaoshuaib has 100 
bananas"""
res = re.match('^Xi.*?(\d+)\s.*s$',content,re.S)
print(res.group())

可能有些朋友会觉得

匹配一个东西还要写开头结尾

有点麻烦

那么就可以使用 re 的另一个方法了

re.search

它会直接去扫描字符串

然后把匹配成功的第一个结果的返回给你

import re

content = """Xiaoshuaib has 100 
bananas"""
res = re.search('Xi.*?(\d+)\s.*s',content,re.S)
print(res.group())

这样子也是可以获取 100 的

但是如果我们的内容是这样的

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""

想要获取所有的 100 呢?

这时候就要用到 re 的另一个方法了

re.findall

 

通过它我们就能轻松的获取所有匹配的内容了

import re

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
res = re.findall('Xi.*?(\d+)\s.*?s;',content,re.S)
print(res)

这里的结果是

['100', '100', '100', '100']

又有朋友觉得

如果我们想直接替换匹配的内容呢

就比如刚刚的字符串

可不可以把 100 直接替换成 250 呢?

那就要用到 re 的另一个方法了

re.sub

可以这样

import re

content = """Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;
Xiaoshuaib has 100 bananas;"""
content = re.sub('\d+','250',content)
print(content)

那么结果就变成了

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

Xiaoshuaib has 250 bananas;

250 个香蕉

吃....得完么??

再来说说 re 的另一个常用到的方法吧

 

re.compile

这个主要就是把我们的匹配符封装一下

import re

content = "Xiaoshuaib has 100 bananas"
pattern = re.compile('Xi.*?(\d+)\s.*s',re.S)
res = re.match(pattern,content) print(res.group())

其实和我们之前写的一样的

res = re.match('^Xi.*?(\d+)\s.*s$',content,re.S)

只不过 compile 一下

便于以后复用

好了

关于 re 模块和正则表达式就介绍完啦

知道了怎么请求数据

也知道了将返回的数据如何正则过滤

那么

爬虫对我们来说还难么?

这次本篇真的完啦

再见

扫一扫

学习 Python 没烦恼

 

近期文章

python爬虫03:那个叫做 Urllib 的库让我们的 python 假装是浏览器

python爬虫04|长江后浪推前浪,Requests 库把 urllib 库拍在沙滩上

对不起,我不应该出轨的!

也不知道为什么

你点了好看之后

你变得更好看了

python爬虫05 | 年轻人,不会正则表达式你睡得着觉?有点出息没有?的更多相关文章

  1. Python爬虫教程-19-数据提取-正则表达式(re)

    本篇主页内容:match的基本使用,search的基本使用,findall,finditer的基本使用,匹配中文,贪婪与非贪婪模式 Python爬虫教程-19-数据提取-正则表达式(re) 正则表达式 ...

  2. Python爬虫学习==>第九章:正则表达式基础

    学习目的: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特点字符.及这些特点字符组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 正式步骤 Step1 ...

  3. python爬虫05正则表达式

    字符 描述 \ 将下一个字符标记为一个特殊字符(File Format Escape,清单见本表).或一个原义字符(Identity Escape,有^$()*+?.[\{|共计12个).或一个向后引 ...

  4. PYTHON 爬虫笔记九:利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集(实战项目二)

    利用Ajax+正则表达式+BeautifulSoup爬取今日头条街拍图集 目标站点分析 今日头条这类的网站制作,从数据形式,CSS样式都是通过数据接口的样式来决定的,所以它的抓取方法和其他网页的抓取方 ...

  5. PYTHON 爬虫笔记八:利用Requests+正则表达式爬取猫眼电影top100(实战项目一)

    利用Requests+正则表达式爬取猫眼电影top100 目标站点分析 流程框架 爬虫实战 使用requests库获取top100首页: import requests def get_one_pag ...

  6. Python爬虫系列:五、正则表达式

    1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. 正则表达式 ...

  7. Python爬虫-05:Ajax加载的动态页面内容

    1. 获取AJAX加载动态页面的内容 1.1. Introduction 如果所爬取的网址是通过Ajax方式加载的,就直接抓包,拿他后面传输数据的文件 有些网页内容使用AJAX加载,只要记得,AJAX ...

  8. python 爬虫004-使用urllib2与正则表达式扒取糗事百科新鲜页首页帖子

    面向过程的方式 #!/usr/bin/env python # -*- coding: utf-8 -*- import urllib2 import sys import re import os ...

  9. (Python爬虫05)完善的爬虫学习大纲

随机推荐

  1. 分享微软官方Demo用的SharePoint 2010, Exchange 2010, Lync 2010虚拟机

    微软官方有一套专门用于SharePoint 2010, Exchange 2010 Demo的虚拟机:SharePoint 2010: Information Worker Demonstration ...

  2. 64位BASM学习随笔(一)

     64位BASM学习随笔(一) Delphi的BASM一直是我最喜爱的内嵌汇编语言,同C/C++的内联汇编相比,它更方便,更具灵活性,由于C/C++的内联汇编仅仅能是或插入式的汇编代码,函数花括号 ...

  3. Spring为了简化java开发採用的四种策略

    以下是<Spring in action>中的总结性语言,记录下来,作为研究源码的主要线索. 1.採用轻量级的pojo.最小侵入式编程. 2.依赖注入(DI)和面向接口编程实现松耦合. 3 ...

  4. 01背包模板、全然背包 and 多重背包(模板)

    转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/ ...

  5. 一句话实现Mysql查询结果带行号

    SELECT @rowno:=@rowno + 1 AS rowno,a.* FROM tableName a,(SELECT @rowno:=0) b

  6. SqlServer还原步骤

    SqlServer还原步骤 2009-09-05 10:32:12|  分类: 数据库|字号 订阅     1 . 删除原有数据库 新建数据库  hywlxt 2. 在master 中新建存储过程 k ...

  7. Codeforces--617B--Chocolate(规律)

     Chocolate Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit ...

  8. Codeforces--633D--Fibonacci-ish(暴力搜索+去重)(map)

    Fibonacci-ish Time Limit: 3000MS   Memory Limit: 524288KB   64bit IO Format: %I64d & %I64u Submi ...

  9. [Apple开发者帐户帮助]一、开始(1)关于您的开发者帐户

    Apple开发人员网站提供了为Apple平台制作出色应用所需的工具和信息.如果您不熟悉Apple平台上的开发,可以免费使用.只需接受Apple开发者协议,即可为您创建一个帐户.使用此帐户下载测试版软件 ...

  10. Appium + python - long_press定位操作实例

    from appium.webdriver.common.touch_action import TouchActionfrom appium import webdriverimport timei ...