正则表达式(三):python re模块
以下示例所使用 python 版本为: 3.7
python 提供 re 模块,来满足正则表达式的使用。在开始介绍 re 模块之前,首先说明一下两个小内容:
- 转义字符 \
转义字符作用是使得字符失去原本的意思,去表示另外一个作用。例如字符 d 表示一个普通的字符 d, 加 \ 转义后 \d 表示数字,字符 s 经转义后,\s 表示空白字符。
如果要匹配转义符号 \ 本身,则需要表达为 \\ 。而在编程语言中要表达两个转义符号 \\,则需要对每个转义符号进行转义,即形式为 \\\\,需要四个转义符号才能完成用于匹配一个转义符号 \ 的正则表达式。
为了减弱转义字符使用上的麻烦,能够将使用者的注意力集中在正则表达式的编写上,这里推荐所有的正则表达式开头使用 r 字符开头,表示正则内容作为原始字符串输入到 re 模块的使用中。即编程环境中 r'\\' 直接作为正则表达式使用,来完成对字符 \ 的匹配。
示例:
import re reg = r'\\' str = '\\' #转义符号,str实际值为\ if re.match(reg,str): print('match {}'.format(str)) ------------------------ 运行结果: match \
- Pattern、Match对象
在re模块中使用正则表达式完成字符串处理有两种方式:
- 在 python 中可以直接使用 re 模块生成 Match 对象,完成字符串处理。
示例:
import re reg = r'abc' str = 'abc' mattern = re.match(reg,str) print(mattern .group()) ------------------------ 运行结果: abc
- 使用 re 模块生成 Pattern 对象,然后使用 Pattern 对象生成 Match 对象,完成字符串处理。
示例:
import re reg = r'abc' str = 'abc' pattern = re.compile(reg) match = pattern.match(str) print(match.group()) ------------------------ 运行结果: abc
这两种方式执行效果基本一样,观察 re 模块源代码:
模块: \Python37\Lib\re.py
# -------------------------------------------------------------------- # public interface def match(pattern, string, flags=0): #第一种方式 """Try to apply the pattern at the start of the string, returning a Match object, or None if no match was found.""" return _compile(pattern, flags).match(string) def compile(pattern, flags=0): #第二种方式 "Compile a regular expression pattern, returning a Pattern object." return _compile(pattern, flags) # -------------------------------------------------------------------- # internals _cache = {} # ordered! _MAXCACHE = 512 def _compile(pattern, flags): # internal: compile pattern if isinstance(flags, RegexFlag): flags = flags.value try: return _cache[type(pattern), pattern, flags] #从缓存字典中查询 except KeyError: pass if isinstance(pattern, Pattern): if flags: raise ValueError( "cannot process flags argument with a compiled pattern") return pattern if not sre_compile.isstring(pattern): raise TypeError("first argument must be string or compiled pattern") p = sre_compile.compile(pattern, flags) if not (flags & DEBUG): if len(_cache) >= _MAXCACHE: # Drop the oldest item try: del _cache[next(iter(_cache))] except (StopIteration, RuntimeError, KeyError): pass _cache[type(pattern), pattern, flags] = p #添加到缓存字典中 return p
观察源码可知, re 模块提供的 compile 函数和 match 函数,都需要先通过 _compile(pattern, flags) 函数生成一个 Pattern 对象,区别在于 match 函数直接在生成 Pattern 对象后调用了 match 函数。
观察 _compile(pattern, flags) 函数体可知,首先会从缓存字典中查询是否已经存在 Pattern 对象,存在则返回,不存在则生成该 Pattern 对象,添加到缓存字典后返回。
由此可知,直接使用 re 模块的 match 函数来生成 Match 对象,和使用 re 模块的 compile 函数生成 Pattern 对象,然后再利用 match 函数生成 Match 对象完成字符串处理,这两种方式都是首先调用 _compile(pattern, flags) 函数生成一个Pattern对象,然后再使用该 Pattern 对象的 match 函数生成 Match 对象。
所以两种方式基本相同,区别只在于当 Pattern 对象多次使用时,第一种方式会存在多次查询缓存操作,且缓存字典容量是有限制的,超出后会删除最先添加的 Pattern 对象,所以推荐所有的正则中都使用构造的 Pattern 对象来完成字符串处理。
下面列出 Pattern 对象中使用到的函数:
函数名 | 作用 |
---|---|
match(string, pos=0, endpos=-1) | 在指定范围内,从指定的起始位置开始匹配,得到匹配对象则返回 |
search(string, pos=0, endpos=-1) | 在指定范围内,从任意位置开始匹配,得到匹配对象则返回 |
findall(string, pos=0, endpos=-1) | 在指定范围内,返回所有匹配结果构成的列表 |
finditer(string, pos=0, endpos=-1) | 在指定范围内,返回所有匹配对象构成的迭代器 |
split(string, maxsplit=0) | 按照指定的分割次数,返回分割得到的结果列表 |
sub(repl, string, count=0) | 按照指定的替换规则和替换次数,返回替换后的结果 |
subn(repl, string, count=0) | 按照指定的替换规则和替换次数,返回替换后的结果和替换次数构成的元组 |
- match 函数
match 函数返回指定范围内,从指定起始位置开始匹配到的对象。使用过程中只有三点需要注意一下:
1. 可以指定匹配的范围,默认范围是 0 到 len(str)
2. 匹配是从指定的起始位置开始的,也就是固定了开始位置
3. 匹配成功则返回,也就是只返回一个匹配对象
示例:
import re reg = r'\d' pattern = re.compile(reg) str1 = 'a1b2c3' match1 = pattern.match(str1) match2 = pattern.match(str1,1) print('match1 = {}'.format(match1)) if match1: print('match1 matched = {}'.format(match1.group())) print('match2 = {}'.format(match2)) if match2: print('match2 matched = {}'.format(match2.group())) 运行结果: match1 = None match2 = <re.Match object; span=(1, 2), match='1'> match2 matched = 1
- search 函数
search 函数返回指定范围内,从任意起始位置开始匹配到的对象。使用过程中只有三点需要注意一下:
1. 可以指定匹配的范围,默认范围是 0 到 len(str)
2. 匹配是从范围内的任意起始位置开始的,也就是不固定开始位置
3. 匹配成功则返回,也就是只返回一个匹配对象
示例:
import re reg = r'\d' pattern = re.compile(reg) str1 = 'a1b2c3' match1 = pattern.search(str1) print('match1 = {}'.format(match1)) if match1: print('match1 matched = {}'.format(match1.group())) 运行结果: match1 = <re.Match object; span=(1, 2), match='1'> match1 matched = 1
比较 match 和 search 函数的使用:两个函数都是一次匹配,得到结果则返回 (None 或 Match 对象),区别在于 match 函数从指定的起始位置开始匹配,search 函数从指定范围内的任意位置开始。
- findall 函数
findall 函数返回指定范围内,所有匹配结果构成的列表。使用过程中只有两点需要注意一下:
1. 可以指定匹配的范围,默认范围是 0 到 len(str)
2. 返回的是一个列表,元素是 str 对象,而非 Match 对象
示例:
import re reg = r'\d' pattern = re.compile(reg) str1 = 'a1b2c3' match1 = pattern.findall(str1) print('match1 = {}'.format(match1)) for element in match1: print('element = {}'.format(element)) 运行结果: match1 = ['1', '2', '3'] element = 1 element = 2 element = 3
- finditer 函数
finditer 函数返回指定范围内,所有匹配对象构成的迭代器。使用过程中只有两点需要注意一下:
1. 可以指定匹配的范围,默认范围是 0 到 len(str)
2. 返回的是一个迭代器,元素是 Match 对象
示例:
import re reg = r'\d' pattern = re.compile(reg) str1 = 'a1b2c3' match1 = pattern.finditer(str1) print('match1 = {}'.format(match1)) for element in match1: print('element = {}'.format(element.group())) 运行结果: match1 = <callable_iterator object at 0x0000000002CA0550> element = 1 element = 2 element = 3
比较 findall 和 finditer 函数的使用:两个函数都是获取所有匹配内容,区别在于 findall 函数返回的是一个列表,元素类型是 str,finditer 函数返回的是一个迭代器,元素类型是 Match 。
- split 函数
split 函数返回根据指定分割次数,分割后得到的结果列表。使用过程中只有两点需要注意一下:
1. 可以指定分割次数,默认值 0 表示全分割
2. 返回的是一个列表,元素是 str 对象
示例:
import re reg = r'\d' pattern = re.compile(reg) str1 = 'a1b2c3' match1 = pattern.split(str1) print('match1 = {}'.format(match1)) for element in match1: print('element = {}'.format(element)) 运行结果: match1 = ['a', 'b', 'c', ''] element = a element = b element = c element =
- sub 函数
sub 函数根据指定替换规则和替换次数,返回替换后内容。使用过程中只有三点需要注意一下:
1. 可以指定替换次数,默认值 0 表示全替换
2. 返回的是一个 str 对象
3. 指定的替换规则可以是 str 对象,可以是一个函数,也可以是分组的引用
示例:
import re def fun(match): return match.group()[::-1] reg = r'(\d)(\d)' pattern = re.compile(reg) str1 = 'a12b34c56' match1 = pattern.sub('__',str1) match2 = pattern.sub(fun,str1) match3 = pattern.sub(r'\2\1',str1) print('match1 = {}'.format(match1)) print('match2 = {}'.format(match2)) print('match3 = {}'.format(match3)) 运行结果: match1 = a__b__c__ match2 = a21b43c65 match3 = a21b43c65
- subn 函数
subn 函数根据指定替换规则和替换次数,返回替换后内容和替换次数构成的元组。使用过程中只有三点需要注意一下:
1. 可以指定替换次数,默认值 0 表示全替换
2. 返回的是一个 str 对象和 int 对象构成的元组
3. 指定的替换规则可以是 str 对象,可以是一个函数,也可以是分组的引用
示例:
import re def fun(match): return match.group()[::-1] reg = r'(\d)(\d)' pattern = re.compile(reg) str1 = 'a12b34c56' match1 = pattern.subn('__',str1,1) match2 = pattern.subn('__',str1,2) print('match1 = {}'.format(match1)) print('match2 = {}'.format(match2)) 运行结果: match1 = ('a__b34c56', 1) match2 = ('a__b__c56', 2)
比较 sub 和 subn 函数的使用:两个函数都是替换匹配内容,区别在于 sub 函数返回的是一个 str 对象,subn 函数返回的是替换后 str 对象和替换次数 int 对象构成的元组。
下面列出 Match 对象中常到的函数:
函数名 | 作用 |
---|---|
group(*args) | 返回指定的分组匹配的结果 |
groups(default=None) | 返回所有分组匹配结果构成的元组 |
span(group=0) | 返回由指定分组匹配结果区间的首尾两个下标值构成的元组 |
start(group=0) | 返回指定分组匹配结果区间的首下标值 |
end(group=0) | 返回指定分组匹配结果区间的尾下标值 |
- group、groups、span、start、end 函数
以上这几个函数作为常用函数,使用方式较为简单:
1. group:返回指定分组匹配的内容,参数为零或者默认值时,返回整个正则表达式匹配结果;参数为多个分组时,返回分组匹配结果构成的元组
2. groups:返回分组匹配结果构成的元组
3. span:返回指定分组匹配结果区间的首尾两个下标值(左闭右开)构成的元组,默认情况下匹配整个正则表达式匹配结果的首尾两个下标值
4. start:返回指定分组匹配结果区间的首下标
5. end:返回指定分组匹配结果区间的尾下标
示例:
import re reg = r'(\d)(\d)' pattern = re.compile(reg) str1 = 'a12b' match1 = pattern.search(str1) print('group 1 = {}'.format(match1.group(1))) print('span 1 = {}'.format(match1.span(1))) print('start 1 = {}'.format(match1.start(1))) print('end 1 = {}'.format(match1.end(1)),end='\n\n') print('group 2 = {}'.format(match1.group(2))) print('span 2 = {}'.format(match1.span(2))) print('start 2 = {}'.format(match1.start(2))) print('end 2 = {}'.format(match1.end(2)),end='\n\n') print('groups = {}'.format(match1.groups())) print('span = {}'.format(match1.span())) print('start = {}'.format(match1.start())) print('end = {}'.format(match1.end()),end='\n\n') print('group 1,2 = {}'.format(match1.group(1,2))) 运行结果: group 1 = 1 span 1 = (1, 2) start 1 = 1 end 1 = 2 group 2 = 2 span 2 = (2, 3) start 2 = 2 end 2 = 3 groups = ('1', '2') span = (1, 3) start = 1 end = 3 group 1,2 = ('1', '2')
Pattern 用作模式处理,Match 用作分组结果提取
比较以上 Pattern 和 Match 两种对象的使用方式,可以发现 Pattern 对象作用如其名称所示,是一种体现正则表达式规则的对象,也就是体现为一种文本模式。其所提供的诸多函数,如: find、search、match 等等,都是拿自身的规则以不同的方式去处理目标文本。而 Match 对象则是对分组结果的操作,Match 对象提供的函数则都是对结果以不同方式的提取,如:groups、span等,获取匹配分组结果的各项数据。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
为什么使用TypeReference
在使用fastJson的时候对于泛型的反序列化很多场景下都会使用到TypeReference,例如: public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("1"); list.add("2"); JSONObject o = new JSONObject(); o.put("k",list); List<String> types = o.getObject("k",List.class); System.out.println(JSON.toJSONString(types)); List<String> types2 = o.getObject("k",new TypeReference<List<String>>(){}); System.out.println(JSON.toJSONString(types2)); } 使用TypeReference可以明确的指定反序列化...
- 下一篇
2018-07-10 第六十五天 jQuery
jQuery 一、jQuery概述 1.jQuery的简介 [1]为什么学习jQuery(JavaScript的缺点): A、JS书写的代码比较的臃肿 B、JS中获得元素对象的方式比较单一 C、JS实现动画效果非常复杂 D、JS的代码对浏览器是有区分的 [2]什么是JQuery JavaScriptQuery:JS的库。 目前最流行的JavaScript函数库,对JavaScript进行了封装。 并不是一门新语言。将常用的、复杂的操作进行函数化封装,直接调用,大大降低了使用JavaScript的难度,改变了使用JavaScript的习惯。 jQuery能做的JavaScript也都能做,但使用jQuery能大幅提高开发效率 由美国人John Resig在2006年推出,目前最新版本是v3.31。 宗旨:Write less,do more(写更少代码,做更多事情) 官方网址http://jquery.com/ 目前jQuery有三个大版本: 1.x:兼容ie678,使用最为广泛的,官方只做BUG维护,功能不再新增。因此一般项目来说,使用1.x版本就可以了,最终版本:1.12....
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- CentOS6,CentOS7官方镜像安装Oracle11G
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- 设置Eclipse缩进为4个空格,增强代码规范
- Mario游戏-低调大师作品
- MySQL8.0.19开启GTID主从同步CentOS8
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果