python正则表达式group用法_【Python】正则表达式用法
导读:正则在各语言中的使用是有差异的,本文以 Python 3 为基础。本文主要讲述的是正则的语法,对于 re 模块不做过多描述,只会对一些特殊地方做提示。
很多人觉得正则很难,在我看来,这些人一定是没有用心。其实正则很简单,根据二八原则,我们只需要懂 20% 的内容就可以解决 80% 的问题了。我曾经有几年几乎每天都跟正则打交道,刚接手项目的时候我对正则也是一无所知,花半小时百度了一下,然后写了几个 demo,就开始正式接手了。三年多时间,我用到的正则鲜有超出我最初半小时百度到的知识的。
1、正则基础
1.1、基础语法
(1)常用元字符
语法描述
\b
匹配单词的开始或结束
\d
匹配数字
\s
匹配任意不可见字符(空格、换行符、制表符等),等价于[ \f\n\r\t\v]。
\w
匹配任意 Unicode 字符集,包括字母、数字、下划线、汉字等
.
匹配除换行符(\n)以外的任意字符
^ 或 \A
匹配字符串或行的起始位置
$ 或 \Z
匹配字符串或行的结束位置
(2)限定词(又叫量词)
语法描述
*
重复零次或更多次
+
重复一次或更多次
?
重复零次或一次
{n}
重复 n 次
{n,}
重复 n 次或更多次
{n,m}
重复 n 到 m 次
(3)常用反义词
语法描述
\B
匹配非单词的开始或结束
\D
匹配非数字
\S
匹配任意可见字符, [^ \f\n\r\t\v]
\W
匹配任意非 Unicode 字符集
除 a、b、c 以外的任意字符
(4)字符族
语法描述
[abc]
a、b 或 c
除 a、b、c 以外的任意字符
[a-zA-Z]
a 到 z 或 A 到 Z
[a-d[m-p]]
a 到 d 或 m 到 p,即 [a-dm-p](并集)
[a-z&&[def]]
d、e 或 f(交集)
[a-z&&[^bc]]
a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]]
a 到 z,减去 m 到 p:[a-lq-z](减去)
以上便是正则的基础内容,下面来写两个例子看下:
s = '123abc你好'
re.search('\d+', s).group()
re.search('\w+', s).group()
结果:
123
123abc你好
是不是很简单?
1.2、修饰符
修饰符在各语言中也是有差异的。
Python 中的修饰符:
修饰符描述
re.A
匹配 ASCII字符类,影响 \w, \W, \b, \B, \d, \D
re.I
忽略大小写
re.L
做本地化识别匹配(这个极少极少使用)
re.M
多行匹配,影响 和
re.S
使 . 匹配包括换行符(\n)在内的所有字符
re.U
匹配 Unicode 字符集。与 re.A 相对,这是默认设置
re.X
忽略空格和 # 后面的注释以获得看起来更易懂的正则。
(1)re.A
修饰符 A 使 \w 只匹配 ASCII 字符,\W 匹配非 ASCII 字符。
s = '123abc你好'
re.search('\w+', s, re.A).group()
re.search('\W+', s, re.A).group()
结果:
123abc
你好
但是描述中还有 \d 和 \D,数字不都是 ASCII 字符吗?这是什么意思?别忘了,还有 全角和半角!
s = '0123456789' # 全角数字
re.search('\d+', s, re.U).group()
结果:
0123456789
(2)re.M
多行匹配的模式其实也不常用,很少有一行行规整的数据。
s = 'aaa\r\nbbb\r\nccc'
re.findall('^[\s\w]*?$', s)
re.findall('^[\s\w]*?$', s, re.M)
结果:
['aaa\r\nbbb\r\nccc'] # 单行模式
['aaa\r', 'bbb\r', 'ccc'] # 多行模式
(3)re.S
这个简单,直接看个例子。
s = 'aaa\r\nbbb\r\nccc'
re.findall('^.*', s)
re.findall('^.*', s, re.S)
结果:
['aaa\r']
['aaa\r\nbbb\r\nccc']
(4)re.X
用法如下:
rc = re.compile(r"""
\d+ # 匹配数字
# 和字母
[a-zA-Z]+
""", re.X)
rc.search('123abc').group()
结果:
123abc
注意,用了 X 修饰符后,正则中的所有空格会被忽略,包括正则里面的原本有用的空格。如果正则中有需要使用空格,只能用 \s 代替。
(5)(?aiLmsux)
修饰符不仅可以代码中指定,也可以在正则中指定。(?aiLmsux) 表示了以上所有的修饰符,具体用的时候需要哪个就在 ? 后面加上对应的字母,示例如下,(?a) 和 re.A 效果是一样的:
s = '123abc你好'
re.search('(?a)\w+', s).group()
re.search('\w+', s, re.A).group()
结果是一样的:
123abc
123abc
1.3、贪婪与懒惰
当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
s = 'aabab'
re.search('a.*b', s).group() # 这就是贪婪
re.search('a.*?b', s).group() # 这就是懒惰
结果:
aabab
aab
简单来说:
所谓贪婪,就是尽可能 多 的匹配;
所谓懒惰,就是尽可能 少 的匹配。
*、+、{n,} 这些表达式属于贪婪;
*?、+?、{n,}? 这些表达式就是懒惰(在贪婪的基础上加上 ?)。
2、正则进阶
2.1、捕获分组
语法描述
(exp)
匹配exp,并捕获文本到自动命名的组里
(?Pexp)
匹配exp,并捕获文本到名称为 name 的组里
(?:exp)
匹配exp,不捕获匹配的文本,也不给此分组分配组号
(?P=name)
匹配之前由名为 name 的组匹配的文本
注意:在其他语言或者网上的一些正则工具中,分组命名的语法是 (?exp) 或 (?'name'exp) ,但在 Python 里,这样写会报错:This named group syntax is not supported in this regex dialect。Python 中正确的写法是:(?Pexp)
示例一:
分组可以让我们用一条正则提取出多个信息,例如:
s = '姓名:张三;性别:男;电话:138123456789'
m = re.search('姓名[::](\w+).*?电话[::](\d{11})', s)
if m:
name = m.group(1)
phone = m.group(2)
print(f'name:{name}, phone:{phone}')
结果:
name:张三, phone:13812345678
示例二:
(?Pexp) 有时还是会用到的, (?P=name) 则很少情况下会用到。我想了一个 (?P=name) 的使用示例,给大家看下效果:
s = '''
张三
30
138123456789
'''
pattern = r'.*?)>(.*?)(?P=name)>'
It = re.findall(pattern, s)
结果:
[('name', '张三'), ('age', '30'), ('phone', '138123456789')]
2.2、零宽断言
语法描述
(?=exp)
匹配exp前面的位置
(?<=exp)
匹配exp后面的位置
(?!exp)
匹配后面跟的不是exp的位置
(?
匹配前面不是exp的位置
注意:正则中常用的前项界定 (?<=exp) 和前项否定界定 (?
(?<=aaa) # 正确
(?<=aaa|bbb) # 正确
(?<=aaa|bb) # 错误
(?<=\d+) # 错误
(?<=\d{3}) # 正确
2.3、条件匹配
这大概是最复杂的正则表达式了。语法如下:
语法描述
(?(id/name)yes|no)
如果指定分组存在,则匹配 yes 模式,否则匹配 no 模式
此语法极少用到,印象中只用过一次。
以下示例的要求是:如果以 _ 开头,则以字母结尾,否则以数字结尾。
s1 = '_abcd'
s2 = 'abc1'
pattern = '(_)?[a-zA-Z]+(?(1)[a-zA-Z]|\d)'
re.search(pattern, s1).group()
re.search(pattern, s2).group()
结果:
_abcd
abc1
2.4、findall
Python 中的 re.findall 是个比较特别的方法(之所以说它特别,是跟我常用的 C# 做比较,在没看注释之前我想当然的掉坑里去了)。我们看这个方法的官方注释:
Return a list of all non-overlapping matches in the string.
If one or more capturing groups are present in the pattern, return
a list of groups; this will be a list of tuples if the pattern
has more than one group.
Empty matches are included in the result.
简单来说,就是
如果没有分组,则返回整条正则匹配结果的列表;
如果有 1 个分组,则返回分组匹配到的结果的列表;
如果有多个分组,则返回分组匹配到的结果的元组的列表。
看下面的例子:
s = 'aaa123bbb456ccc'
re.findall('[a-z]+\d+', s) # 不包含分组
re.findall('[a-z]+(\d+)', s) # 包含一个分组
re.findall('([a-z]+(\d+))', s) # 包含多个分组
re.findall('(?:[a-z]+(\d+))', s) # ?: 不捕获分组匹配结果
结果:
['aaa123', 'bbb456']
['123', '456']
[('aaa123', '123'), ('bbb456', '456')]
['123', '456']
零宽断言中讲到 Python 中前项界定必须是定长的,这很不方便,但是配合 findall 有分组时只取分组结果的特性,就可以模拟出非定长前项界定的效果了。
结语
其实正则就像是一个数学公式,会背公式不一定会做题。但其实这公式一点也不难,至少比学校里学的数学简单多了,多练习几次也就会了。
python正则表达式group用法_【Python】正则表达式用法相关推荐
- java中include标签的用法_原 ng-include用法分析以及多标签页面的简单实现方式
在平时的项目开发中,应该会经常遇到上图所示的需求,就是在一个页面中有多个标签,被选中的标签颜色会高亮显示,切换不同标签显示相应的不同内容.如果内容代码过多则写在同一个html文件就会显得特别乱,所以这 ...
- python查看excel编码格式_[Python]实现处理读写xlsx xls excel文件格式(含中文处理方法)...
最近有个需求要处理excel 格式的数据,数据量比较大.用传统的语言似乎不太好处理,于是改用python实现,这里记录一下实现过程. 首先,科普一下xlsx xls的excel文件区别是什么. xls ...
- java正则表达式替换特殊字符_使用正则表达式替换报表名称中的特殊字符(推荐)...
正则表达式,又称规则表达式.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表通常被用来检索.替换那些符合某个模式(规则)的文 ...
- python多进程编程实例_[python] Python多进程编程技术实例分析
这篇文章主要介绍了Python多进程编程技术,包括了线程.队列.同步等概念及相关的技巧总结,需要的朋友可以参考下 本文以实例形式分析了Python多进程编程技术,有助于进一步Python程序设计技巧. ...
- python快速爬虫视频_“python怎么快速爬虫视频“python 爬网页视频教程
用python怎样爬网页 # coding:utf8 import cookielib import urllib2 url = "http://blog.uouo123.com" ...
- python朋友圈刷屏_“Python太火了!请救救Java!”9万程序员刷屏朋友圈 !
没想到有生之年,笔者能观察到"霸主陨落"的过程,继PLPY4月榜单官宣,Python躺赢,再度"夺"冠,实力甩下Java和C后,近期,Stack Overflo ...
- python 打包 小文件_[Python][小知识][NO.5] 使用 Pyinstaller 打包成.exe文件
1.安装 pyinstaller 插件 cmd命令:pip install PyInstaller PS . o.o 不知道 easy_install 的百度吧. 2.pyinstaller 简介 他 ...
- python shell如何打开_“python shell怎么打开“python shell启动教程
python shell怎么打开 1.简介:如何在python中运行shell(bash命令) 2.工具/原料:python库:os.py 3.方法:import os command = 'date ...
- python输出文本居中_#python PIL ImageDraw text 文本居中#
python pip pil有什么东西 你所问的问题实是属1.先参考[教程]Python中的内置的和方的模块搞懂PIL是属于第三方Python模块2.再参考:[待完善][总结]Python安装第三方的 ...
- 正则表达式在python中的应用_学习正则表达式在python中的应用
目的:对文本的处理,正则表达式的功能很强大,可以很巧妙的过滤.匹配.获取想要的字符串,是必须学习的技能,这里只记录常用的写法,详细文档可以参看官方帮助文档. 环境:ubuntu 16.04 pytho ...
最新文章
- 8.1shell介绍 8.2命令历史 8.3命令补全和别名 8.4通配符 8.5输入输出重定向
- Linux 下使用openSSL 生成RSA密钥对
- 一个mybatis处理batch的插件,类似于pageHelper插件
- weblogic 负载均衡搭建
- js获取用户当前所在城市(ip)
- 《从零开始学Swift》学习笔记(Day 59)——代码排版
- Matlab之矩阵行列式、秩、迹的求解
- windows/linuxjdk安装,jdk1.6升级到1.7
- Exchange 跨林迁移 Part3 添加域信任关系
- 随手记_重建的五花八门的点云地图效果(供娱乐)
- spark学习5(hbase集群搭建)
- win7设置固定IP重启后无法上网,ipconfig显示为自动配置IPV4 169.254的地址
- 杭州电子科技大学ACM竞赛试题----百步穿杨
- Rhythmbox中mp3中文乱码解决
- html页面如何拉长,HTML可以拉长的logo
- windows下用cmd卸载程序
- SpringMVC实现i18n和主题切换
- 吴军老师《给中学生/大学生的书单》----Yohao整理
- log4,log4net,Log4配置,log4net使用实例,.net中使用LOG4输出日志,LOG4纪录日志
- 肖锰:浪潮GS开发平台学习札记(一)——服务器端安装
热门文章
- android 程序崩溃日记捕捉
- python判断是否在docker中
- node process.env.NODE_ENV 使用 cross-env 配置 设置
- jmeter集合点使用方法:Synchronizing Timer
- string容量JAVA_java的StringBuilder类的长度和容量有什么区别呢?
- 1006 换个格式输出整数 (15分)
- middle函数C语言,C语言函数调用栈(三)
- [poj3321]Apple Tree_dfs序_树状数组
- Ubuntu下gcc多版本共存和版本切换
- 201521123057 《Java程序设计》第12周学习总结