Python中正则表达式讲解
正则表达式是匹配字符串的强大武器,它的核心思想是给字符串定义规则,凡是符合规则的字符串就是匹配了,否则就是不合法的。在介绍Python的用法之前,我们先讲解一下正则表达式的规则,然后再介绍在Python中如何运用。
如果直接给出字符,那么就是精确的匹配,例如‘abc’当然是匹配’abc’了。
- \d可以匹配数字(0-9)
- \D和\d相反,就是说只要不是0-9,都可以匹配
- \w可以匹配字母或者数字(0-9|a-z|A-Z)
- \W和\w相反,就是说只要不是字母和数字,都可以匹配
- \s可以匹配空格,\n,\t,\r,\f
- \S和\s相反
- . 可以匹配除了\n以外的任意字符
第一步先说这些内容,Python提供re模块,包含所有正则表达式的功能,看下面的程序演示:
#如何判断正则表达式是否匹配,使用re.match()
import re
a=re.match('\d','1')
b=re.match('\d','s')
print(a)
print(b)
输出:
<_sre.SRE_Match object at 0x000000000065A510>
None
这里说一下,如果match()方法匹配的话,返回一个Match对象,否则返回None
为了方便观察程序运行结果,我们使用if判断来输出结果,下面再看一个例子
import re
def is_match(a):
if a!=None:
print('yes!')
else:
print('no!')
a=re.match('\d','123abc')
b=re.match('\d\d','123abc')
c=re.match('\d\d\d','123abc')
d=re.match('\d\d\d\d','123abc')
is_match(a)
is_match(b)
is_match(c)
is_match(d)
输出:
yes!
yes!
yes!
no!
现在来讲解上面的代码,我们知道\d可以匹配一个0-9的数字,所以re.match(‘\d’,’123abc’)中的\d匹配的是字符串‘123abc’中的1,至于后面的’23abc’不用管它。一个\d我只用匹配一个数字就可以了。re.match(‘\d\d’,’123abc’)中的两个\d分别匹配的是字符串’123abc’中的‘1’和‘2’,后面的‘3abc’不用管。re.match(‘\d\d\d\d’,’123abc’)中前3个\d分别匹配的是‘1’,‘2’,‘3’,当第4个\d去匹配‘a’的时候发现不能匹配,所以最后一个不能匹配上,输出None。再看几个例子体会下吧
为了减少代码量,下面的代码我会直接写主要的代码部分,输出结果用注释代替
a=re.match('\w','123abc') #yes
b=re.match('\w','abc123') #yes
c=re.match('\w','Abc123') #yes
a=re.match('.','abc') #yes
b=re.match('.','Abc') #yes
c=re.match('.','12bc') #yes
d=re.match('.','*2bc') #yes
e=re.match('.','\n2bc') #no
如果我们要匹配变长的字符,可以在\d,\w,\s, . 的后面使用下面的符号
* 表示任意个字符(包括0个)
+表示至少一个字符
?表示0个或1个字符
{n}表示n个字符
{n,m}表示n-m个字符
a=re.match('\d*','123') #yes
# *表示任意个字符,包括0个,所以\d*可以匹配0个数字,所以match('\d*','abc')可以匹配
b=re.match('\d*','abc') #yes
c=re.match('\d+','1abc') #yes
# +表示至少1个字符,\d+表示至少1个数字,所以匹配不成功
d=re.match('\d+','abc') #no
a=re.match('\d?','123') #yes
b=re.match('\d?','abc') #yes
c=re.match('\d{3}','1234') #yes
#\d{3}代表3个数字,而'12'只有2个,所以不匹配
d=re.match('\d{3}','12') #no
#'12abc'前3个'12a'不全是数字
e=re.match('\d{3}','12abc') #no
a=re.match('\d{0,3}','abc') #yes
b=re.match('\d{0,3}','12abc') #yes
c=re.match('\d{0,3}','1234bc') #yes
还有更加精确的匹配,用[ ]表示范围,例如:
[0-9]匹配1个数字,和\d一样
[a-z]匹配1个小写字母
[A-Z]匹配1个大写字母
\ _匹配下划线
[0-9a-zA-Z]可以匹配1个数字或者字母,等价于\w
[0-9a-zA-Z\ _]可以匹配1个数字或者字母或者下划线,一般是变量的命名规则
[0-9] | [a-z]匹配1个数字或者小写字母,使用的是 | 符号
^表示以什么开头,例如^[0-9]就是以数字开头
$表示以什么结尾
a1=re.match('[0-9]','123') #yes
a2=re.match('[a-z]','abc') #yes
a3=re.match('[A-Z]','Abc') #yes
a4=re.match('[0-9a-zA-Z]','Abc') #yes
b1=re.match('[0-9a-zA-Z]','12bc') #yes
b2=re.match('[0-9a-zA-Z]','abc') #yes
b3=re.match('[0-9a-zA-Z]','张康abc') #no
b4=re.match('[0-9a-zA-Z\_]','_abc') #yes
a=re.match('^[0-9a-zA-Z\_][0-9]','a1bc') #yes
b=re.match('^[0-9a-zA-Z\_][a-z]','Abc') #yes
c=re.match('^[0-9a-zA-Z\_][A-Z]','1Bbc') #yes
d=re.match('^[0-9a-zA-Z\_][0-9]','1abc') #no
e=re.match('^[0-9a-zA-Z\_]','_1bc') #yes
a=re.match('^[0-9a-z]+[A-Z]$','1234A') #yes
b=re.match('^[0-9a-z]+[A-Z]$','1234a') #no
正则表达式还可以用来切分字符串(切分字符串)
import re
a=re.split('\s+','a b c')
print(a)
输出:
['a', 'b', 'c']
关于字符串中的split()函数,不明白的请参考我的另一篇博文。上面的代码的意思是以空格为切分符,把字符串分成n段,并以list的形式返回。
如果还想把逗号加进去,让空格和逗号都变成分隔符,看下面的代码:
import re
a=re.split('[\s\,]+','a b c ,d,f e')
print(a)
输出:
['a', 'b', 'c', 'd', 'f', 'e']
正则表达式还可以用来提取子串(分组)
用( )表示的就是要提取的分组(Group),把想要提取的子串在正则表达式中用( )括起来,例如我要提取带区号的固定电话号的每一部分,看代码演示:
import re
a=re.match('(\d{4})\-(\d{7})','0370-5163700')
g0=a.group(0)
g1=a.group(1)
g2=a.group(2)
print(g0)
print(g1)
print(g2)
输出:
0370-5163700
0370
5163700
\d{4}匹配的是0370,因为我要提取它,所以用()括起来,代表一个分组
\ - 匹配的是 - ,因为这里 - 是特殊字符,需要转义,就像下划线需要转义\ _,这里我不需要提取这个 - ,所以不用加括号。
\d{7}匹配的是5163700,这是需要提取的第二个分组,所以需要括起来。
还有一点需要注意,无论什么时候,group(0)提取的都是原来的字符串,你要提取的分组从group(1)开始。
正则表达式的贪婪匹配
正则表达式匹配默认是贪婪匹配,也就是匹配尽可能多的字符,看个例子吧!
import re
a=re.match('^(\d+)(1*)$','12345611111')
print('第一组:'+a.group(1))
print('第二组:'+a.group(2))
输出:
第一组:12345611111
第二组:
按照正常的理解\d+应该匹配123456,1*匹配11111,但是由于正则表达式是默认贪婪匹配,\d+匹配了全部数字。怎么才能不让它贪婪匹配呢,很简单,在后面加个问号?就可以了
import re
a=re.match('^(\d+?)(1*)$','12345611111')
print('第一组:'+a.group(1))
print('第二组:'+a.group(2))
输出:
第一组:123456
第二组:11111
编译
在Python中使用正则表达式时,re模块内部会干两件事情:
- 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
- 用编译后的正则表达式去匹配字符串。
在编写网站的时候,有可能我们会对用户注册时输入的用户名或者邮箱等进行正则验证,那么一个正则表达式可能会匹配成千上万个用户名或者邮箱,每次都需要先编译后匹配,那么效率显得很低。那么为了提高效率,我们可以先编译正则表达式,只需要编译一次,然后用的时候再匹配。
import re
#由字母或者下划线开头,由数字,字母,下划线组成长度为6-20的字符串
re_c=re.compile('^[a-zA-Z\_][\w\_]{5,19}$')
print(re_c.match('a123456789a123456789'))
输出:
<_sre.SRE_Match object at 0x000000000065A510>
编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用再次给出正则串。
以上的内容只是正则表达式的九牛一毛,关于其他的正则表达式用法请读者自己查阅,如读者发现错误,欢迎指正。
Python中正则表达式讲解的更多相关文章
- python 中 正则表达式 的应用
python 中 正则表达式 的应用 最近作业中出现了正则表达式,顺便学习了一下. python比较厉害的一点就是自带对正则表达式的支持,用起来很方便 正则表达式 首先介绍一下什么是正则表达式. 正则 ...
- 第11.20节 Python 中正则表达式的扩展功能:后视断言、后视取反
一. 引言 在<第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反>中老猿介绍了前视断言和前视取反,与二者对应的还有后视断言和后视取反. 二. (?<=-)后视 ...
- Python中正则表达式简介
目录 一.什么是正则表达式 二.正则表达式的基础知识 1. 原子 1)普通字符作为原子 2)非打印字符作为原子 3) 通用字符作为原子 4) 原子表 2. 元字符 1)任意匹配元字符 2)边界限制元字 ...
- python中正则表达式 re.findall 用法
在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配. 其中,re.findall() 函数可以遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表. 在python源代码中 ...
- python中正则表达式re模块详解
正则表达式是处理字符串的强大工具,它有自己特定的语法结构,有了它,实现字符串的检索,替换,匹配验证都不在话下. 当然,对于爬虫来说,有了它,从HTML里提取想要的信息就非常方便了. 先看一下常用的匹配 ...
- python中正则表达式在中文字符串匹配时的坑
之前一直有使用python 正则表达式来做中文字符串或者中英文数字混合的字符串的匹配,发现有不少情况下会匹配失灵或者结果混乱,并且在不同操作系统上匹配结果也不一致,查了很久都不知道是什么原因.今天终于 ...
- js中正则表达式与Python中正则表达式的区别
今天女票让我帮她写一个js中的正则,来提取电话号码,对于正则规则来说,js与python是基本没有区别的,重点的区别是在一些函数与方法中. python中的正则提取: import re str = ...
- 关于Python中正则表达式的反斜杠问题
之前总是搞不明白正则表达式中的反斜杠的问题.今天经过查阅资料终于搞明白了. 其中最重要的一点就是Python自己的字符串中定义的反斜杠也是转义字符,而正则表达式中的反斜杠也是转义字符,所以正则表达式中 ...
- python中正则表达式
正则表达式是一种通用的字符串匹配技术,是不会因为编程语言不一样而发生变化的如果想查找对应规则的字符串,就可以用正则表达式python中要使用正则表达式需使用re模块,它是正则表达式在python中的封 ...
随机推荐
- AtCoder Regular Contest 078 D
D - Fennec VS. Snuke Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement F ...
- typedef与复杂声明
参考 [1] http://www.cnblogs.com/bakari/archive/2012/08/28/2659889.html [2]<C专家编程> [3 ]http://www ...
- STM32的低功耗模式
一 待机模式standby和STOP模式的区别: 进入低功耗模式:都一样,都是先关闭相应时钟,关闭相应外设,配置相应所有IO口(浮动输入),然后配置相应的唤醒中断源,中断影响的O口,然后调用相应函数进 ...
- 语义分割丨DeepLab系列总结「v1、v2、v3、v3+」
花了点时间梳理了一下DeepLab系列的工作,主要关注每篇工作的背景和贡献,理清它们之间的联系,而实验和部分细节并没有过多介绍,请见谅. DeepLabv1 Semantic image segmen ...
- box-shadow四周阴影
box-shadow 前面两个值为 纵向阴影 和 横向阴影 把这两个值都设置为 0 就是四边都有阴影 border:#074A99 0px solid; box-shadow: 0 0 10px #0 ...
- #52. 【UR #4】元旦激光炮 (交互式题)
链接:http://uoj.ac/problem/52 刚刚越过绝境长城,只见天空中出现了炫目的光芒 —— 圣诞老人出现了. 元旦三侠立刻进入战斗.生蛋侠.圆蛋侠和零蛋侠分别有 na,nb,ncna, ...
- BS3 多级菜单
<div class="container"> <div class="row"> <h2>Multi level drop ...
- Java之内部类、包及代码块
个人通俗理解: 1.内部类:有点类似于写在父类中的子类,根据位置不一样为不同的名字,和相应的访问方式不同:不过要访问外部类的话,需要充分运用好this(本类)的这个关键字:要是需要快速的创建子类对象的 ...
- Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)
一.基本概念 强制下线功能功能应该算是比较常见的了,很多应用程序都具备这个功能,比如你的QQ号或者微信号在别处登录了,就会将你强制挤下线.只需要在界面上弹出一个对话框,让用户无法进行任何其他的操作,必 ...
- Servlet和JSP之自定义标签学习
此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述. 参考:慕课网的<JSP自定义标签>视频; <Servlet.JSP和Sprin ...