python 正则表达式re使用模块(match()、search()和compile())
摘录 python核心编程
python的re模块允许多线程共享一个已编译的正则表达式对象,也支持命名子组。下表是常见的正则表达式属性:
| 函数/方法 | 描述 |
| 仅仅是re模块函数 | |
| compile(pattern,flags=0) | 使用任何可选的标记来编译正则表达式的模式 ,然后返回一个正则表达式对象 |
| re模块函数和正则表达式对象的方法 | |
| match(pattern,string,flags=0) | 尝试使用带有可选标记的正则表达式的模式来匹配字符串,成功则返回匹配的对象,失败则返回None |
| search(pattern,string,flags=0) | 使用可选标记搜索字符串中第一次出现的正则表达式模式,成功则返回匹配对象,失败则返回None |
| findall(pattern,string[,flags]) | 查找字符串中所有(非重复)出现的正则表达式模式,返回一个匹配列表 |
| finditer(pattern,string,[,flags]) | 和findall()函数相同,但返回的是一个迭代器。对于每次匹配,迭代器都返回一个匹配对象 |
| split(pattern,string,max=0) | 根据正则表达式的模式分隔符,split函数将字符串分割为列表,然后返回成功匹配的列表,分割最多操作max次(默认分割所有匹配成功的位置) |
| re模块函数和正则表达式对象方法 | |
| sub(pattern,repl,string,count=0) | 使用repl替换正则表达式模式在字符串中出现的位置,除非定义count,否则替换所有 |
| purge() | 清除隐式编译的正则表达式模式 |
| 常用的匹配对象方法 | |
| group(num=0) | 返回整个匹配对象,或者编号为num的特定子组 |
| groups(default=None) | 返回一个包含所有匹配子组的元组(如果没有,则返回一个空元组) |
| groupdict(default=None) | 返回一个包含所有匹配的命名子组的字典,所有子组名称作为字典的键(如没有,则返回一个空字典) |
| 常用的模块属性 | |
| re.I、re.IGNORECASE | 不区分大写的匹配 |
| re.L、re.LOCALE | 根据所使用的本地语言环通过\w\W\b\B\s\S实现匹配 |
| re.M、re.MULTILINE | ^和$分别匹配目标字符串中行的起始和结尾,而不是严格的匹配整个字符串本身的开始和结尾 |
| re.S、re.DOTALL | 点号.通常匹配除了换行符\n之外的所有单个字符,该标记表示点号能够匹配全部字符 |
| re.X、re.VERBOSE | 通过反斜线转义,否则所有空格加上#(以及在该行中所有后续问题)都被忽略,除非在一个字符类中或者允许注释并且提高可读性 |
compile()编译正则表达式
在模式匹配发生之前,正则表达式模式必须编译成正则表达式对象,而且正则表达式在执行的过程中可能进行多次的比较操作。所以,强烈建议使用compile函数进行预编译,用以提升程序的执行性能。其实所有的模块函数会对已编译的对象进行缓存。
匹配对象及其group()和groups()方法
处理正则表达式的时候,除了正则表达式对象外,还有一个叫做匹配对象的类型。成功调用match()和search()返回的对象就是匹配对象。
匹配对象有两个主要的方法:group()和groups()函数。二者的区别在于:前者可以返回整个匹配对象或者特定子组,后者仅返回包含全部子组的元组。
match()方法实现匹配字符串
match()方法视图从字符串的起始位置部分对模式进行匹配,成功则返回一个匹配对象,失败返回None,而匹配对象的group()方法能够显示成功的匹配:
>>> import re
>>> m = re.match('foo','foo')
>>> m
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> if m is not None:
... m.group()
...
'foo'
>>> n = re.match('hello,foo!','foo')
>>> if n is not None:n.group()
...
>>> n
第二个例子中,由于foo并不是在开始的位置,所有没有成功。
search()在一个字符串中查找模式
search()的工作方式和match()完全一致,只是search()会用他的字符串参数,在任意位置对给定正则表达式模式搜索第一次出现的匹配情况。成功则返回匹配对象,否则返回None:
>>> n = re.match('foo','hello,foo!')
>>> if n is not None:ngroup()
...
>>>
>>> n = re.search('foo','hello,foo!')
>>> if n is not None:n.group()
...
'foo'
匹配多个字符
>>> bt = 'bat|bet|bit'
>>> m = re.match(bt,'bat')
>>> if m is not None:m.group()
...
'bat'
>>> m = re.match(bt,'blt')
>>> if m is not None:m.group()
...
>>> m = re.match(bt,'he bit me')
>>> if m is not None:m.group()
...
>>> m = re.search(bt,'he bit me')
>>> if m is not None:m.group()
...
'bit'
匹配任何单个字符
先看一个点号不能匹配换行符的示例:
>>> end = '.end'
>>> m = re.match(end,'bend')
>>> if m is not None:m.group()
...
'bend'
>>> m = re.match(end,'\nbend')
>>> if m is not None:m.group()
...
>>> m = re.search(end,'The end')
>>> if m is not None:m.group()
...
' end
再看一下搜索一个真正的句点的示例:
>>> patt314 = '3.14'
>>> pi_ptt = '3\.14'
>>> m = re.match(pi_ptt,'3.14')
>>> if m is not None:m.group()
...
'3.14'
>>> m = re.match(patt314,'')
>>> if m is not None:m.group()
...
''
>>> m = re.search(patt314,'3.14')
>>> if m is not None:m.group()
...
'3.14'
>>> m = re.match(pi_ptt,'3014')
>>> if m is not None:m.group()
...
上述例子又让我们强化认识了'3.14'和'3\.14'的区别。
创建字符集
下面的示例,用于展示[cr][23][dp][o2]和r2d2|c3po之间的区别:(会发现r2d2|c3po的限制将比[cr][23][dp][o2]更为严格)
>>> m = re.match('[cr][23][dp][o2]','c3po')
>>> if m is not None:m.group()
...
'c3po'
>>> m = re.match('[cr][23][dp][o2]','c2do')
>>> if m is not None:m.group()
...
'c2do'
>>> m = re.match('r2d2|c3po','c2do')
>>> if m is not None:m.group()
...
>>> m = re.match('r2d2|c3po','r2d2')
>>> if m is not None:m.group()
...
'r2d2'
重复、特殊字符以及分组
正则表达式最常见的情况包括:特殊字符的使用、正则表达式模式的重复出现、使用小括号对匹配模式的各部分进行分组和提取
我们可以使用正则表达式'\w+@\w+\.com'表示一个简单的邮件地址。当我们需要再域名前加上主机名,例如www.xxx.com,那就必须修改现有的正则表达式。同时,为了表示主机名是可选的,需要创建一个模式来匹配主机名,使用?操作符来表示该模式出现0或者一次: \w+@(\w+\.)?\w+\.com
>>> patt = '\w+@(\w+\.)?\w+\.com'
>>> re.match(patt,'somebody@xxx.com').group()
'somebody@xxx.com'
>>> re.match(patt,'somebody@www.xxx.com').group()
'somebody@www.xxx.com'
>>> re.match(patt,'somebody@xxx.yyy.zzz.com').group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
针对上述例子的最后一句,下面进行扩展,允许任意数量的中间子域名存在:
>>> patt = '\w+@(\w+\.)*\w+\.com'
>>> re.match(patt,'somebody@xxx.yyy.zzz.com').group()
'somebody@xxx.yyy.zzz.com'
一般的,采用使用小括号来匹配和保存子组,以便于后续处理,而不是确定一个正则表达式匹配之后在一个单独的子程序里面手动编码来解析字符串:
>>> m = re.match('\w\w\w-\d\d\d','abc-123')
>>> if m is not None:m.group()
...
'abc-123'
>>> m = re.match('\w\w\w-\d\d\d','abc-xyz')
>>> if m is not None:m.group()
...
扩展,修改上述正则表达式,使该正则表达式能够提取字母数字字符串和数字:
>>> m = re.match('(\w\w\w)-(\d\d\d)','abc-123')
>>> m.group()
'abc-123'
>>> m.group(1)
'abc'
>>> m.group(2)
''
>>> m.groups()
('abc', '')
下面的例子展示了不同的分组排列,以及group()和groups()函数的执行情况:
>>> m = re.match('ab','ab')
>>> m.group()
'ab'
>>> m.groups()
()
>>> m = re.match('(ab)','ab')
>>> m.group()
'ab'
>>> m.group(1)
'ab'
>>> m.group(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group
>>> m.groups()
('ab',)
>>> m = re.match('(a)(b)','ab')
>>> m.group()
'ab'
>>> m.group(1)
'a'
>>> m.group(2)
'b'
>>> m.groups()
('a', 'b')
>>> m = re.match('(a(b))','ab')
>>> m.group()
'ab'
>>> m.group(1)
'ab'
>>> m.group(2)
'b'
>>> m.groups()
('ab', 'b')
匹配字符串的起始和结尾以及单词边界
下面例子展示了表示位置的正则表达式操作符。更多的用于表示搜索而不是匹配,因为match()总是从字符串开始位置进行匹配:
>>> import re
>>> m = re.search('^The','The end')
>>> if m is not None:
... m.group()
...
'The'
>>> m = re.search('^The','end The')
>>> if m is not None:
... m.group()
...
>>> m = re.search(r'\bthe','bite the dog')
>>> if m is not None:
... m.group()
...
'the'
>>> m = re.search(r'the','bite the dog')
>>> if m is not None:
... m.group()
...
'the'
>>> m = re.search(r'the','bitethe dog')
>>> if m is not None:
... m.group()
...
'the'
>>> m = re.search(r'\Bthe','bite the dog')
>>> if m is not None:
... m.group()
...
使用findall()和finditer()查找每一次出现的位置
findall()查询字符串中某个正则表达式模式全部的非重复出现情况。于search()执行的搜索字符串类似,但是不同之处在于:findall()总是返回一个列表,列表按顺序包含所有成功匹配的部分:
>>> re.findall('car','carry the barcardi to the car')
['car', 'car', 'car']
finditer()于findall类似,但是返回的是一个迭代器,使得更节省内存。(对于迭代器,可以使用迭代器相关的知识提取内容)
使用sub()和subn()搜索和替换
两者的作用基本一致,都是将某个字符串中所有匹配正则表达式的部分进行某种形式的替换,相比于sub(),subn()还返回一个表示替换的总数,替换后的字符串和表示替换总数的数字一起作为一个拥有两个元素的元组返回:
>>> re.subn('X','Mr.Smith','attn:X\n\nDear X,\n')
('attn:Mr.Smith\n\nDear Mr.Smith,\n', 2)
>>> print(re.sub('X','Mr.Smith','attn:X\n\nDear X,\n'))
attn:Mr.Smith
Dear Mr.Smith,
在限定模式上使用split()分割字符串
先来一个普通的字符串分割:
>>> re.split(':','str1:str2:str3')
['str1', 'str2', 'str3']
再来见识一下巨大威力的分割效果:例如用于web站点的简单解析器,这是普通的字符串分割没有的强大的处理方式
>>> DATA = (
... 'Moutain view, CA 94040',
... 'Sunny, CA',
... 'Los Altos, 94023',
... 'Cuper 95014',
... 'Palo Alto CA',
... )
>>> for i in DATA:
... print(re.split(', |(?= (?:\d{5}|[A-Z]{2})) ',i))
...
['Moutain view', 'CA', '']
['Sunny', 'CA']
['Los Altos', '']
['Cuper', '']
['Palo Alto', 'CA']
上述例子中的正则表达式使用了一个组件:使用split语句基于逗号分割字符串,或者如果空格紧跟在五个数字或者两个大写字母之后,就用split语句分割该空格。而这种分割效果很难用str.split()达到。
这里涉及到的正则表达式的扩展符号的使用,足够让我们另写一篇文章介绍了。
python 正则表达式re使用模块(match()、search()和compile())的更多相关文章
- python正则表达式之re模块方法介绍
python正则表达式之re模块其他方法 1:search(pattern,string,flags=0) 在一个字符串中查找匹配 2:findall(pattern,string,flags=0) ...
- Python正则表达式与re模块介绍
Python中通过re模块实现了正则表达式的功能.re模块提供了一些根据正则表达式进行查找.替换.分隔字符串的函数.本文主要介绍正则表达式先关内容以及re模块中常用的函数和函数常用场景. 正则表达式基 ...
- python 正则表达式 (重点) re模块
京东的注册页面,打开页面我们就看到这些要求输入个人信息的提示.假如我们随意的在手机号码这一栏输入一个11111111111,它会提示我们格式有误.这个功能是怎么实现的呢?假如现在你用python写一段 ...
- Python正则表达式与hashlib模块
菜鸟学python第十六天 1.re模块(正则表达式) 什么是正则表达式 正则表达式是一个由特殊字符组成的序列,他能帮助对字符串的某种对应模式进行查找. 在python中,re 模块使其拥有全部的正则 ...
- python正则表达式与re模块-02
正则表达式 正则表达式与python的关系 # 正则表达式不是Python独有的,它是一门独立的技术,所有的编程语言都可以使用正则 # 但要在python中使用正则表达式,就必须依赖于python内置 ...
- Python正则表达式与re模块
在线正则表达式测试 http://tool.oschina.net/regex/ 常见匹配模式 模式 描述 \w 匹配字母数字及下划线 \W 匹配非字母数字下划线 \s 匹配任意空白字符,等价于 [\ ...
- python 正则表达式与re模块
一.正则表达式 用途 用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. #### 简单地说 就是用于字符串匹配的 字符组 在 ...
- [ python ] 正则表达式及re模块
正则表达式 正则表达式描述: 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个‘规则字符串’,这个‘规则字符串’用来 表达对字符串的一种过滤 ...
- python正则表达式之re模块使用
python第一个正则表达式 https://www.imooc.com/learn/550 r'imooc' Pattern Match result In [2]: import re In [ ...
随机推荐
- tensorflow:模型的保存和训练过程可视化
在使用tf来训练模型的时候,难免会出现中断的情况.这时候自然就希望能够将辛辛苦苦得到的中间参数保留下来,不然下次又要重新开始. 保存模型的方法: #之前是各种构建模型graph的操作(矩阵相乘,sig ...
- day20191012笔记
课程默写笔记: 1.程序架构 C/S 客户端/服务器端 B/S 浏览器/服务器端 2.Tomcat应用服务器 tomcat默认端口号是80:tomcat配置文件中通常端口的定义是8080: 3.使用开 ...
- 【开发工具 - MySQL】之不能插入中文的问题
新安装的MySQL数据库,在安装的时候设置了字体为UTF8,但在使用insert语句插入中文的时候还是会报错. 具体解决方法:在MySQL控制台中输入以下设置代码: SET character_set ...
- 线程池&进程池
线程池&进程池 池子解决什么问题? 1.创建/销毁线程伴随着系统开销,如果过于频繁会影响系统运行效率 2.线程并发数量过多,抢占系统资源,从而导致系统阻塞甚至死机 3.能够刚好的控制和管理池子 ...
- MyBatis系列(一) MyBatis入门
前言 MyBatis官方文档:https://mybatis.org/mybatis-3/zh/index.html MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由 ...
- 阿里巴巴 Service Mesh 落地的架构与挑战
点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 | 方克明(溪翁 ...
- luogu P3830 [SHOI2012]随机树
输入格式 输入仅有一行,包含两个正整数 q, n,分别表示问题编号以及叶结点的个数. 输出格式 输出仅有一行,包含一个实数 d,四舍五入精确到小数点后 6 位.如果 q = 1,则 d 表示叶结点平均 ...
- bundle 的生成和使用
一.bundle 的生成 1.打开XCode,创建iOS版用的bundle资源包,有两种方式:第一种直接将工作,open in finder.在目录中直接新建文件夹,文件夹以bundle格式.文件夹 ...
- Evevt Loop 事件循环
目录 JavaScript 是一门单线程的语言 一.什么是event Loop的执行机制 练习 异步任务-setTimeout 练习1: 练习2: 练习3: 练习4: 二 事件队列作用 同步任务 例1 ...
- 机器学习预测时label错位对未来数据做预测
前言 这篇文章时承继上一篇机器学习经典模型使用归一化的影响.这次又有了新的任务,通过将label错位来对未来数据做预测. 实验过程 使用不同的归一化方法,不同得模型将测试集label错位,计算出MSE ...