正则表达式在爬虫项目中应用很广泛,主要方面就是在字符串处理方面,经常会涉及到字符串格式的校验,用起来经常要查看文档才能完成,所以抽了个时间将正则的内容复习了一下。

Start re---导入re模块使用

#coding=utf-8
# 导⼊re模块
import re
# 使⽤match⽅法进⾏匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上⼀步匹配到数据的话,可以使⽤group⽅法来提取数据
result.group()

其中正则表达式就是Pattern,一般用p来代替,后面是要匹配的字符串,如果匹配到,result类型是(Match Object),否则返回None,注意不是返回"",因为""也是字符串的一部分,不可能作为正则返回值,其中group()方法,返回字符串的匹配部分。

example1:(匹配以darren为开头的语句)
#coding=utf-8
import re
result = re.match("darren","darren.cn")
result.group()

运行结果为:

darren

注意re.match() 能够匹配出以xxx开头的字符串,也即^符号的用法不是很明显,后文会讲到。

正则表达式表示字符

正则表达式的单字符匹配
字符 功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符
\d 匹配数字,即0-9
\D 匹配⾮数字,即不是数字
\s 匹配空⽩,即 空格,tab键
\S 匹配⾮空⽩
\w 匹配单词字符,即a-z、A-Z、0-9、_
\W 匹配⾮单词字符

example2:(单个字符匹配小试牛刀)

1. ---------------------------
In [31]: re.match(".", "\n") In [32]: re.match("...", "ab") In [33]: re.match("...", "abc")
Out[33]: <_sre.SRE_Match at 0x10b16d510> In [34]: re.match("...", "abcd")
Out[34]: <_sre.SRE_Match at 0x10b16d578> 2. -----------------------------
In [35]: re.match("\d", "1")
Out[35]: <_sre.SRE_Match at 0x10b16d5e0> In [36]: re.match("\d", "2")
Out[36]: <_sre.SRE_Match at 0x10b16d648> In [37]: re.match("\d", "a") In [38]: re.match("\D", "a")
Out[38]: <_sre.SRE_Match at 0x10b16d6b0> 3. ------------------------------ In [39]: re.match("\s", " a")
Out[39]: <_sre.SRE_Match at 0x10b16d718> In [40]: re.match("\s", "\ta")
Out[40]: <_sre.SRE_Match at 0x10b16d780> In [41]: re.match("\s", "\na")
Out[41]: <_sre.SRE_Match at 0x10b16d7e8> In [42]: re.match("\S", "\na") 4. -------------------------------
In [43]: re.match("\w", "\na") In [44]: re.match("\w", "-a") In [45]: re.match("\w", "_a")
Out[45]: <_sre.SRE_Match at 0x10b16d850> In [46]: re.match("\w", "1a")
Out[46]: <_sre.SRE_Match at 0x10b16d8b8> In [47]: re.match("\W", "1a") In [48]: 5. -----------------------------
In [54]: re.match("1[34578]","18")
Out[54]: <_sre.SRE_Match at 0x10b16de00> In [55]: re.match("1[34578]","19") In [56]: re.match("1[^34578]","19")
Out[56]: <_sre.SRE_Match at 0x10b1a8030> In [57]: re.match("1[^34578]","1a")
Out[57]: <_sre.SRE_Match at 0x10b1a8098> In [58]: re.match("1[^3^4^5^7^8]","1a")
Out[58]: <_sre.SRE_Match at 0x10b1a8100> In [59]: re.match("1[^34578]","1a") 6. ------------------------------
\d == [0-9]
\D == [^0-9]
\w == [a-zA-Z0-9_]

正则表达式表示数量、匹配多个字符的相关格式

匹配多个字符的相关格式
字符 功能
* 匹配前⼀个字符出现0次或者⽆限次,即可有可⽆
+ 匹配前⼀个字符出现1次或者⽆限次,即⾄少有1次
? 匹配前⼀个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前⼀个字符出现m次
{m,} 匹配前⼀个字符⾄少出现m次
{m,n} 匹配前⼀个字符出现从m到n次
 
 
example3:(匹配多个字符)
7.----------------------
In [61]: re.match("\d*", "")
Out[61]: <_sre.SRE_Match at 0x10b1a81d0> In [62]: re.match("\d*", "abc")
Out[62]: <_sre.SRE_Match at 0x10b1a8238> In [63]: re.match("\d*", "123")
Out[63]: <_sre.SRE_Match at 0x10b1a82a0> In [64]: re.match("\d+", "1")
Out[64]: <_sre.SRE_Match at 0x10b1a8308> In [65]: re.match("\d+", "abc") In [66]: re.match("\d+", "123abc")
Out[66]: <_sre.SRE_Match at 0x10b1a8370> In [67]: re.match("\d?", "abc")
Out[67]: <_sre.SRE_Match at 0x10b1a83d8> In [68]: re.match("\d?", "1abc")
Out[68]: <_sre.SRE_Match at 0x10b1a8440> In [69]: re.match("\d?", "1234abc")
Out[69]: <_sre.SRE_Match at 0x10b1a84a8> In [70]: re.match("\d?[a-z]", "1234abc") In [71]: re.match("\d*[a-z]", "1234abc")
Out[71]: <_sre.SRE_Match at 0x10b1a8648> In [72]: re.match("\d+[a-z]", "1234abc")
Out[72]: <_sre.SRE_Match at 0x10b1a86b0> In [73]: re.match("\d?[a-z]", "1234abc") In [74]: re.match("\d+[a-z]", "1234abc")
Out[74]: <_sre.SRE_Match at 0x10b1a8780> In [75]: re.match("\d\d\d\d\d\d\d\d[a-z]", "1234abc") In [75]: re.match("\d{4}[a-z]", "1234abc")
Out[75]: <_sre.SRE_Match at 0x10b1a87e8> In [76]: re.match("\d{3}[a-z]", "1234abc") In [77]: re.match("\d{5}[a-z]", "1234abc") In [78]: re.match("\d{3,}[a-z]", "1234abc")
Out[78]: <_sre.SRE_Match at 0x10b1a8920> In [79]: re.match("\d{5,}[a-z]", "1234abc") In [80]: re.match("\d{3,5}[a-z]", "1234abc")
Out[80]: <_sre.SRE_Match at 0x10b1a8988> In [81]: re.match("1[35678]\d{9}", "1811111111") In [82]: re.match("1[35678]\d{9}", "18111111111")
Out[82]: <_sre.SRE_Match at 0x10b1a89f0> In [83]: re.match("1[35678]\d{9}", "18111111111abcd")
Out[83]: <_sre.SRE_Match at 0x10b1a8a58>

匹配分组

匹配分组
字符 功能
| 匹配左右任意⼀个表达式
(ab) 将括号中字符作为⼀个分组
\num 引⽤分组num匹配到的字符串
(?P<name>)  分组起别名
(?P=name) 引⽤别名为name分组匹配到的字符串
example4:(匹配分组的练习)
--------------------------------------------
In [19]: s
Out[19]: '\\nabc' In [20]: re.match("\\\\nabc", s)
Out[20]: <_sre.SRE_Match object; span=(0, 5), match='\\nabc'> In [21]: re.match(r"\\nabc", s)
Out[21]: <_sre.SRE_Match object; span=(0, 5), match='\\nabc'> In [23]: re.match(r"1[35678]\d{9}$","18111111111")
Out[23]: <_sre.SRE_Match object; span=(0, 11), match='1811
1111111'> In [24]: re.match(r"1[35678]\d{9}$","18111111111234") In [25]: re.match(r"^1[35678]\d{9}$","18111111111")
Out[25]: <_sre.SRE_Match object; span=(0, 11), match='1811
1111111'> In [26]: re.match(r"^\w+ve","hover")
Out[26]: <_sre.SRE_Match object; span=(0, 4), match='hove'> In [27]: re.match(r"^\w+ve\b","hover") In [28]: re.match(r"^\w+\bve\b","hover") In [29]: re.match(r"^\w+\bve\b","ho ve r") In [30]: re.match(r"^\w+\s\bve\b","ho ve r")
Out[30]: <_sre.SRE_Match object; span=(0, 5), match='ho ve'> In [31]: re.match(r"^.+\bve\b","ho ve r")
Out[31]: <_sre.SRE_Match object; span=(0, 5), match='ho ve'> 0 1 2
12 34 60 50
100 In [37]: re.match(r"[1-9]\d?$|0$|100$", "200") In [38]: re.match(r"[1-9]\d?$|0$|100$", "100")
Out[38]: <_sre.SRE_Match object; span=(0, 3), match='100'> In [39]: re.match(r"[1-9]\d?$|0$|100$", "84")
Out[39]: <_sre.SRE_Match object; span=(0, 2), match='84'> In [40]: re.match(r"[1-9]\d?$|0$|100$", "9")
Out[40]: <_sre.SRE_Match object; span=(0, 1), match='9'> In [41]: re.match(r"[1-9]\d?$|0$|100$", "084") In [42]: re.match(r"[1-9]\d?$|0$|100$", "08") In [43]: re.match(r"[1-9]\d?$|0$|100$", "0")
Out[43]: <_sre.SRE_Match object; span=(0, 1), match='0'> In [44]: re.match(r"[1-9]?\d?$|100$", "0")
Out[44]: <_sre.SRE_Match object; span=(0, 1), match='0'> /book/(med)/(inner) <html></html> socket connect
socket.send()
socket.recv("<h1>匹配分组</h1> 字符") Out[47]: '<h1>匹配分组</h1>' In [48]: result.group(1
...: )
Out[48]: '匹配分组' In [49]: result = re.match(r"(<h1>).*(</h1>)", "<h1>匹配分组</h1>") In [50]: result.group(1)
Out[50]: '<h1>' In [51]: result.group(2)
Out[51]: '</h1>' In [52]: result.group(0)
Out[52]: '<h1>匹配分组</h1>' In [53]: result.groups()
Out[53]: ('<h1>', '</h1>') In [54]: result.groups()[0]
Out[54]: '<h1>' In [58]: re.match(r"<.+><.+>.+</.+></.+>", s)
Out[58]: <_sre.SRE_Match object; span=(0, 25), match='<html><h1>itcast</h1></h>'> In [59]: re.match(r"<(.+)><(.+)>.+</\2></\1>", s) In [60]: s = "<html><h1>itcast</h1></html>" In [61]: re.match(r"<(.+)><(.+)>.+</\2></\1>", s)
Out[61]: <_sre.SRE_Match object; span=(0, 28), match='<html><h1>itcast</h1></html>'> In [62]: s = "<html><h1>itcast</html></h1>" In [63]: re.match(r"<(.+)><(.+)>.+</\2></\1>", s) In [64]: s = "<h2><h>itcast</h></h2>" In [65]: re.match(r"<(.+)><(.+)>.+</\2></\1>", s)
Out[65]: <_sre.SRE_Match object; span=(0, 22), match='<h2><h>itcast</h></h2>'>

re模块的其他用法

a-zA-z0-9_    @163 126 gmail . com cn net
######################search的用法,用来找出匹配的邮箱################################
In [73]: s = "<html><h1>itcast</h1></html>" In [74]: re.match(r"<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>", s
...: )
Out[74]: <_sre.SRE_Match object; span=(0, 28), match='<html><h1>itcast</h1></html>'> In [75]: s = "<html><h1>itcast</h1></ht>" In [76]: re.match(r"<(?P<key1>.+)><(?P<key2>.+)>.+</(?P=key2)></(?P=key1)>", s
...: ) In [77]: In [77]: s = "<html><h1>itcast</h1></html>" In [78]: re.search(r"itcast", s)
Out[78]: <_sre.SRE_Match object; span=(10, 16), match='itcast'> In [79]: re.search(r"^itcast$", s) In [80]: re.search(r"^itcast", s) In [81]: s = "itcast</h1></html>" In [82]: re.search(r"^itcast", s)
Out[82]: <_sre.SRE_Match object; span=(0, 6), match='itcast'> In [83]: In [87]: r = re.search(r"\w+</h1>", s) In [88]: r.group()
Out[88]: 'itcast</h1>'
###############################findAll()---找出所有匹配的字符串######################
In [89]: r = re.findall(r"\w+</h1>", s) In [90]: r
Out[90]: ['itcast</h1>', 'itheima</h1>'] In [108]: re.sub(r"</?\w+>", "",s)
Out[108]: '\n 岗位职责:\n完成推荐算法、数据统计、接口、后良好的自我驱动力和职业素养,工作积极主动、结果导向\n \n技术要对象分析和设计,了解设计模式\n2、掌握HTTP协议,熟悉MVC、MVVM等概念计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种\n4、掌握NoSQL、M、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js\n \n加分项理统计,机器学习,sklearn,高性能,大并发。\n\n ' In [109]: s = "itcast:php,python,cpp-java" In [110]: re.split(r":|,|-", s)
Out[110]: ['itcast', 'php', 'python', 'cpp', 'java'] In [111]: In [113]: s="This is a number 234-235-22-423" In [114]: r = re.match(r".+(\d+-\d+-\d+-\d+)", s) In [115]: r.group(1)
Out[115]: '4-235-22-423' In [116]: r = re.match(r"(.+)(\d+-\d+-\d+-\d+)", s) In [117]: r.groups()
Out[117]: ('This is a number 23', '4-235-22-423') In [118]: r = re.match(r"(.+?)(\d+-\d+-\d+-\d+)", s) In [119]: r.groups()
Out[119]: ('This is a number ', '234-235-22-423') In [120]: In [123]: s = "http://www.interoem.com/messageinfo.asp?id=35"
#############################sub 将匹配到的数据进⾏替换#####################
'''
"http://www.interoem.com/messageinfo.asp?id=35"------>
http://www.interoem.com/

'''In [124]: re.sub(r"http://.+?/", "", s)Out[124]: 'messageinfo.asp?id=35'In [125]: re.sub(r"http://.+?/(.*)", "", s)Out[125]: ''In [126]: re.sub(r"(http://.+?/).*", lambda x: x.group(1), s)Out[126]: 'http://www.interoem.com/'In [127]: s = "hello world ha ha"In [128]: re.split(r" +", s)Out[128]: ['hello', 'world', 'ha', 'ha']In [129]: re.findall(r"\b[a-zA-z]+\b", s)Out[129]: ['hello', 'world', 'ha', 'ha']



python贪婪和⾮贪婪



Python⾥数量词默认是贪婪的(在少数语⾔⾥也可能是默认⾮贪婪),总是尝试匹配尽可能多的字符;⾮贪婪则相反,总是尝试匹配尽可能少的字符。在"*","?","+","{m,n}"后⾯加上?,使贪婪变成⾮贪婪。正则表达式模式中使⽤到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满⾜匹配最⻓字符串,在我们上⾯的例⼦⾥⾯,“.+”会从字符串的启始处抓取满⾜模式的最⻓字符,其中包括我们想得到的第⼀个整型字段的中的⼤部分,“\d+”只需⼀位字符就可以匹配,所以它匹配了数字“4”,⽽“.+”则匹配了从字符串起始到这个第⼀位数字4之前的所有字符。解决⽅式:⾮贪婪操作符“?”,这个操作符可以⽤在"*","+","?"的后⾯,要求正则匹配的越少越好。

>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'

tips

  • Python中字符串前⾯加上 r 表示原⽣字符串,在pattern中匹配到的.是匹配的.而不是原生的.所以要进行\.
  • re.match()是从左到右匹配的,返回值是匹配的字符串
  • \d*表示匹配\d可以0或者n个而不是理解为具体的只能是0000  111 222这种
  • .表示任意字符 匹配的是内容 *表示的是数量上的
  • 疑问:1111 1234 这种怎么挑选写出来,  1{4}  \d{4}
  • <_sre.SRE_Match object; span=(0, 6), match='itcast'> python3中匹配到的样子。python2中结果是另外一种<_sre.SRE_Match at 0x10b1a8a58>
  • 一些常用的等价方法,看个人习惯

{1,} == +

{0,1} == ?

\w == [a-zA-Z0-9]

s="\\nabc"

  • 通常在正则匹配的时候,都会加上r,就会简单很多不用去想\转义的问题,直接匹配s中的内容即可
  • [^abc] == [^a^b^c] 注意它与 ^放在外面的区别用法
  • 边界匹配只匹配状态,不匹配字符,不占位
  • 注意|的用法以及(a|b|c)这样的,在使用中|是表示两边所有的或即()|(),而后者只是括号中(|)的两者
  • 在匹配邮箱时候的注意点,即使前面有r""   在.处也要转义\.至于如果字符串中真的是\.应该写为\\\.
  • search()找到第一个就返回
  • findAll()则是匹配到所有的

python核心高级学习总结7---------正则表达式的更多相关文章

  1. python核心高级学习总结5--------python实现线程

    在代码实现上,线程的实现与进程的实现很类似,创建对象的格式都差不多,然后执行的时候都是用到start()方法,与进程的区别是进程是资源分配和调度的基本单位,而线程是CPU调度和分派的基本单位.其中多线 ...

  2. python核心高级学习总结8------动态性、__slots__、生成器、迭代器、装饰、闭包

    python的动态性 什么是动态性呢,简单地来说就是可以在运行时可以改变其结构,如:新的函数.对象.代码都可以被引进或者修改,除了Python外,还有Ruby.PHP.javascript等也是动态语 ...

  3. python核心高级学习总结6------面向对象进阶之元类

    元类引入 在多数语言中,类就是一组用来描述如何生成对象的代码段,在python中同样如此,但是在python中把类也称为类对象,是的,你没听错,在这里你只要使用class关键字定义了类,其解释器在执行 ...

  4. python核心高级学习总结3-------python实现进程的三种方式及其区别

    python实现进程的三种方式及其区别 在python中有三种方式用于实现进程 多进程中, 每个进程中所有数据( 包括全局变量) 都各有拥有⼀份, 互不影响 1.fork()方法 ret = os.f ...

  5. python核心高级学习总结1---------*args和**kwargs

    *args 和 ** kwargs 的用法 首先,这两者在用法上都是用来补充python中对不定参数的接受. 比如下面的列子 def wrappedfunc(*args, **kwargs): pri ...

  6. python核心编程学习记录之正则表达式

  7. python核心高级学习总结4-------python实现进程通信

    Queue的使用 Queue在数据结构中也接触过,在操作系统里面叫消息队列. 使用示例 # coding=utf-8 from multiprocessing import Queue q = Que ...

  8. python核心高级学习总结2----------pdb的调试

    PDB调试 def getAverage(a,b): result =a+b print("result=%d"%result) return result a=100 b=200 ...

  9. 零基础的学习者应该怎么开始学习呢?Python核心知识学习思维分享

    近几年,Python一路高歌猛进,成为最受欢迎的编程语言之一,受到无数编程工作者的青睐. 据悉,Python已经入驻部分小学生教材,可以预见学习Python将成为一项提高自身职业竞争力的必修课.那么零 ...

随机推荐

  1. 腾讯云--cdn静态内容上传刷新

    一.cdn缓存刷新 当静态内容需要更新时,通常会往COS覆盖上传,不覆盖删除上传等进行更新资源或删除对象存储中的内容. 如果配置的CDN缓存过期时间较长,会导致文件更新后其他边缘节点依旧会缓存旧资源: ...

  2. Spider_基础总结1_Request(get/post__url传参_headers_timeout)+Reponse

    网络爬虫(一) 一.简介 1.robot协议(爬虫协议):这个协议告诉引擎哪些页面可以抓取,哪些不可以 -User-agent:爬虫引擎 -allow:允许robot访问的URL -disallow: ...

  3. Spring笔记(8) - @EventListener注解探究

    在上文中讲了Spring的事件监听机制,流程是:定义事件.监听器,发布事件,控制台输出监听到的事件内容. 在上文的扩展中 使用 @EventListener 注解来自定义监听器,监听指定的事件,比如下 ...

  4. 邻居子系统 arp 状态图

  5. 一文带你玩转对象存储COS文档预览

    随着"互联网+"的发展,各行各业纷纷"去纸化",商务合同.会议纪要.组织公文.商品图片.培训视频.学习课件.随堂讲义等电子文档无处不在.而要查看文档一般需要先下 ...

  6. 剑指offer刷题(算法类_1)

    斐波那契数列 007-斐波拉契数列 题目描述 题解 代码 复杂度 008-跳台阶 题目描述 题解 代码 复杂度 009-变态跳台阶 题目描述 题解 代码 复杂度 010-矩形覆盖 题目描述 题解 代码 ...

  7. 搭建zookeeper集群(伪集群)

    jdk环境 上传zk压缩包 解压缩 复制三份 mkdir /usr/local/zk_cluster cp -r zookeeper-3.4.6 /usr/local/zk_cluster/zooke ...

  8. phpstorm 远程调式 php

    https://cloud.tencent.com/developer/article/1561767 超时设置 fastcgi: ``` 1. apache module的情况下: 修改配置文件 h ...

  9. 渗透测试神器Cobalt Strike使用教程

    Cobalt Strike是一款渗透测试神器,常被业界人称为CS神器.Cobalt Strike已经不再使用MSF而是作为单独的平台使用,它分为客户端与服务端,服务端是一个,客户端可以有多个,可被团队 ...

  10. Guitar Pro吉他指弹入门——双手泛音

    曾经有一段时间在琴行里经常遇到有人来试琴,很多人试弹得曲子就是郑成河的<Flaming>,直译过来就是热情的意思.这首曲子里面有很多泛音存在,吉他泛音类似于钟鸣或者摇铃的声音,是一种令人耳 ...