python中re模块知识点总结


Posted in Python onJanuary 17, 2021

一、什么是正则表达式?

正则表达式,又称规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。

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

二、正则表达式的匹配规则

1.表示字符

  • ·:匹配任意除换行符'\n'外的字符,但是在DOTALL模式中也可以匹配换行符'\n'
  • \:转义字符,使后一个字符改变原来的意思,如果字符串中想匹配*,可以使用\*,也可以使用字符集[*]
  • [...]:字符集,匹配字符集中列出的任意字符。字符可以逐个列出,也可以给出范围,比如[a-z],[0-9],第一个字符是^表示取反。所有特殊字符在字符集中都失去其原有的特殊含义。如果想使用']','-'或者'^',可以在前面加上\,或者将]或者-放在首位,将^放在非首位

2.预定义字符集(可写在字符集[]中)

  • \d:数字[0-9]
  • \D:非数字[^0-9]
  • \s:空白字符[<空格>,\t,\n,\r,\f,\v]
  • \S:非空白字符[^\s]
  • \w:单词字符[a-zA-Z0-9_]
  • \W:非单词字符[^\w]

3.表示数量

  • *:匹配前一个字符0次或无限次,即可有可无
  • +:匹配前一个字符出现1次或者无限次,即至少有1次
  • {m}:匹配前一个字符出现m次
  • {m,}:匹配前一个字符至少出现m次
  • {,n}:匹配前一个字符至多出现n次
  • {m,n}:匹配前一个字符出现从m到n次

4.表示边界

  • ^:匹配字符串开头。在多行模式中匹配每一行的开头
  • $:匹配字符串结尾。在多行模式中匹配每一行的结尾
  • \A:仅匹配字符串开头
  • \Z:仅匹配字符串结尾
  • \b:匹配单词边界,\w和\W之间
  • \B:匹配非单词边界,[^\b]

5.匹配分组

  • |:匹配左右任意一个表达式
  • (...):被括起来的表达式作为一个分组,从表达式左边开始,每遇到一个'(',编号+1。分组表达式作为一个整体,后面可接数量词。表达式中的|仅在该分组中有效
  • (?P<name>):分组,除了原有的编号以外,再给分组取一个别名
  • (?P=<name>):引用别名为<name>的分组匹配到的字符串
  • \<number>:引用编号为<number>的分组匹配到的字符串

6.特殊构造(不作为分组)

  • (?:...):(...)的不分组版本,用于使用'|'或后面接上数量词,比如(?:[1-9]?\d|100)表示匹配数字0-100,(?:abc){2}表示匹配abcabc
  • 剩下的一些不常见,略

三、re模块

在 Python中,我们可以使用内置的 re 模块来使用正则表达式。与大多数编程语言相同,正则表达式里使用'\'作为转义字符,这就可能造成反斜杠困扰。Python里的原生字符串很好地解决了这个问题,只需要在字符串前面加上'r'前缀。

re模块的一般使用步骤:

  1. 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
  2. 通过 Pattern 对象提供的一系列方法对文本进行匹配查找

1.compile函数

compile 函数用于编译正则表达式,生成一个 Pattern 对象。必须传入的第一个参数是'规则字符串',另外可以通过第二个参数(flags)来指定匹配模式。

常见的匹配模式:

  1. re.I(re.IGNORECASE): 忽略大小写
  2. re.M(MULTILINE): 多行模式,改变'^'和'$'的行为
  3. re.S(DOTALL): 点任意匹配模式,改变'.'的行为,可以匹配'\n'
import re

# 将正则表达式编译成 Pattern对象,并指定匹配模式为点任意匹配模式
pattern = re.compile(r'\d+',re.S)

2.Pattern 对象的一些常用方法

match方法

match 方法用于查找字符串的头部(也可以指定起始位置),它是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果。

它的一般使用形式如下:

match(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。因此,当你不指定 pos 和 endpos 时,match 方法默认匹配字符串的头部。

当匹配成功时,返回一个 Match 对象,如果没有匹配上,则返回 None。

Match对象常用的方法:

  • group(([group1, …]):用于获得一个或多个分组匹配的字符串,如果传入多个分组编号,则返回的结果为元组形式。当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
  • groups():获得所有分组匹配到的字符串所构成的元组
  • start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
  • end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
  • span([group]) 方法返回 (start(group), end(group)),获取分组匹配的子串在整个字符串中的起始和结束位置构成的元组。

通过一些例子来熟悉一下:

In [1]: import re

In [2]: pattern = re.compile(r"(\w+) (\d+)")

In [3]: m = pattern.match('hello 123')

In [4]: m.group(1)
Out[4]: 'hello'

In [5]: m.group(1,2)
Out[5]: ('hello', '123')

In [6]: m.group()
Out[6]: 'hello 123'

In [7]: m.groups()
Out[7]: ('hello', '123')

In [8]: m.start(1)
Out[8]: 0

In [9]: m.start(2)
Out[9]: 6

In [10]: m.end(1)
Out[10]: 5

In [11]: m.span(1)
Out[11]: (0, 5)

In [12]: m.span(2)
Out[12]: (6, 9)

search方法

search 方法用于查找字符串的任何位置,它也是一次匹配,只要找到了一个匹配的结果就返回,而不是查找所有匹配的结果

它的一般使用形式如下:

search(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。

看看例子

>>> import re
>>> pattern = re.compile('\d+')
>>> m = pattern.search('one12twothree34four') # 这里如果使用 match 方法则不匹配
>>> m
<_sre.SRE_Match object at 0x10cc03ac0>
>>> m.group()
'12'
>>> m = pattern.search('one12twothree34four', 10, 30) # 指定字符串区间
>>> m
<_sre.SRE_Match object at 0x10cc03b28>
>>> m.group()
'34'
>>> m.span()
(13, 15)

findall方法

上面的 match 和 search 方法都是一次匹配,只要找到了一个匹配的结果就返回。然而,在大多数时候,我们需要搜索整个字符串,获得所有匹配的结果。

findall 方法的使用形式如下:

findall(string[, pos[, endpos]])

其中,string 是待匹配的字符串,pos 和 endpos 是可选参数,指定字符串的起始和终点位置,默认值分别是 0 和 len (字符串长度)。

findall 以列表形式返回全部能匹配的子串,如果没有匹配,则返回一个空列表。

看个例子:

import re

#re模块提供一个方法叫compile模块,提供我们输入一个匹配的规则
#然后返回一个pattern实例,我们根据这个规则去匹配字符串
pattern = re.compile(r'\d+\.\d*')

#通过partten.findall()方法就能够全部匹配到我们得到的字符串
result = pattern.findall("123.141593, 'bigcat', 232312, 3.15")

#findall 以 列表形式 返回全部能匹配的子串给result
for item in result:
 print(item)

运行结果:

123.141593
3.15

finditer方法

finditer 方法的行为跟 findall 的行为类似,也是搜索整个字符串,获得所有匹配的结果。但它返回一个顺序访问每一个匹配结果(Match 对象)的迭代器。

举例:

In [1]: import re

In [2]: pattern = re.compile(r"\d+")

In [3]: iter = pattern.finditer('hello123world456 haha789')

In [4]: iter
Out[4]: <callable_iterator at 0x7fb824fe2a90>

In [5]: for m in iter:
 ...:  print(m.group())
 ...: 
123
456
789

split方法

split 方法按照能够匹配的子串将字符串分割后返回列表

它的使用形式如下:

split(string[, maxsplit])

其中,maxsplit 用于指定最大分割次数,不指定将全部分割。

举个例子:

In [1]: import re

In [2]: pattern = re.compile(r"[\d\s]")

In [3]: pattern.split('hello1word2aaa bbb')
Out[3]: ['hello', 'word', 'aaa', 'bbb']

In [4]: pattern.split('hello1word2aaa bbb',2)
Out[4]: ['hello', 'word', 'aaa bbb']

sub方法

sub 方法用于替换。

它的使用形式如下

sub(repl, string[, count])

其中,repl 可以是字符串也可以是一个函数:

  • 如果 repl 是字符串,则会使用 repl 去替换字符串每一个匹配的子串,并返回替换后的字符串,另外,repl 还可以使用 id 的形式来引用分组,但不能使用编号 0;
  • 如果 repl 是函数,这个方法应当只接受一个参数(Match 对象),并返回一个字符串用于替换(返回的字符串中不能再引用分组)。
  • count 用于指定最多替换次数,不指定时全部替换。
In [1]: import re

In [2]: pattern = re.compile(r'\d+')

In [3]: pattern.sub('100','hello20 world30')#将所有匹配到的数据替换成100
Out[3]: 'hello100 world100'

In [4]: pattern.sub('100','hello20 world30',1)#只替换第一个数据为100
Out[4]: 'hello100 world30'

In [5]: def add(temp):
 ...: '''将匹配到的数据加1'''
 ...:  strNum = temp.group()
 ...:  num = int(strNum)+1
 ...:  return str(num)
In [6]: pattern.sub(add,'hello20 world30')#将所有匹配到的数据加1
Out[6]: 'hello21 world31'

In [7]: pattern.sub(add,'hello20 world30',1)#只将匹配到的第一个数据加1
Out[7]: 'hello21 world30'

四、贪婪模式与非贪婪模式

  • 贪婪模式:在整个表达式匹配成功的前提下,尽可能多的匹配
  • 非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配
  • 在表示数量的"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪
In [1]: import re

In [2]: pattern = re.compile(r'\d+')

In [3]: pattern.match('123456789').group()
Out[3]: '123456789'

In [4]: pattern = re.compile(r'\d+?')#关闭贪婪模式

In [5]: pattern.match('123456789').group()#非贪婪模式下,?只匹配一个字符
Out[5]: '1'

In [6]: pattern = re.compile(r'<div>.*</div>')

In [7]: pattern.match('<div>test1</div>bb<div>test2</div>').group()
Out[7]: '<div>test1</div>bb<div>test2</div>'

In [8]: pattern = re.compile(r'<div>.*?</div>')#关闭贪婪模式

In [9]: pattern.match('<div>test1</div>bb<div>test2</div>').group()
Out[9]: '<div>test1</div>'

到此这篇关于python中re模块知识点总结的文章就介绍到这了,更多相关python中re模块的使用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
一个小示例告诉你Python语言的优雅之处
Jul 04 Python
python通过pip更新所有已安装的包实现方法
May 19 Python
python操作列表的函数使用代码详解
Dec 28 Python
python简单操作excle的方法
Sep 12 Python
python 实现语音聊天机器人的示例代码
Dec 02 Python
用Anaconda安装本地python包的方法及路径问题(图文)
Jul 16 Python
解决pycharm启动后总是不停的updating indices...indexing的问题
Nov 27 Python
Python 音频生成器的实现示例
Dec 24 Python
python列表推导和生成器表达式知识点总结
Jan 10 Python
python numpy生成等差数列、等比数列的实例
Feb 25 Python
Python TKinter如何自动关闭主窗口
Feb 26 Python
解决numpy数组互换两行及赋值的问题
Apr 17 Python
史上最详细的Python打包成exe文件教程
Jan 17 #Python
python制作微博图片爬取工具
Jan 16 #Python
python工具——Mimesis的简单使用教程
Jan 16 #Python
Python 内存管理机制全面分析
Jan 16 #Python
python des,aes,rsa加解密的实现
Jan 16 #Python
python math模块的基本使用教程
Jan 16 #Python
详解Python模块化编程与装饰器
Jan 16 #Python
You might like
自动跳转中英文页面
2006/10/09 PHP
memcache命令启动参数中文解释
2014/01/13 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(一)
2014/06/23 PHP
关于Laravel Route重定向的一个注意点
2017/01/16 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
动态修改DOM 里面的 id 属性的弊端分析
2008/09/03 Javascript
javascript打开新窗口同时关闭旧窗口
2009/01/16 Javascript
JS 文件传参及处理技巧分析
2010/05/13 Javascript
Jquery.LazyLoad.js修正版下载,实现图片延迟加载插件
2011/03/12 Javascript
jQuery获得内容和属性示例代码
2014/01/16 Javascript
javascript比较两个日期的先后示例代码
2014/12/31 Javascript
推荐10 款 SVG 动画的 JavaScript 库
2015/03/24 Javascript
jquery中live()方法和bind()方法区别分析
2016/06/23 Javascript
基于JavaScript实现购物网站商品放大镜效果
2016/09/06 Javascript
微信小程序 wx.request方法的异步封装实例详解
2017/05/18 Javascript
学习Vue组件实例
2018/04/28 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
2018/07/10 Javascript
Angular8基础应用之表单及其验证
2019/08/11 Javascript
[01:57]2018年度DOTA2最具潜力解说-完美盛典
2018/12/16 DOTA
Python安装pycurl失败的解决方法
2018/10/15 Python
Django ManyToManyField 跨越中间表查询的方法
2018/12/18 Python
解决Python在导入文件时的FileNotFoundError问题
2020/04/10 Python
借助HTML5 Canvas来绘制三角形和矩形等多边形的方法
2016/03/14 HTML / CSS
HTML5 实现图片上传预处理功能
2020/02/06 HTML / CSS
Lungolivigno Fashion官网:高级时装在线购物
2020/10/17 全球购物
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
计算机求职自荐信范文
2014/04/19 职场文书
专家推荐信模板
2014/05/09 职场文书
让世界充满爱观后感
2015/06/10 职场文书
2015年高中班级工作总结
2015/07/21 职场文书
2015年党务工作者个人工作总结
2015/10/22 职场文书
中小学教师继续教育心得体会
2016/01/19 职场文书
优秀家长事迹材料(2016推荐版)
2016/02/29 职场文书
为什么不建议在go项目中使用init()
2021/04/12 Golang
图文详解matlab原始处理图像几何变换
2021/07/09 Python