【Python入门】23.正则表达式

摘要:正则表达式的基本介绍;常用字符和语法介绍;re模块;贪婪匹配


写在前面:为了更好的学习python,博主记录下自己的学习路程。本学习笔记基于廖雪峰的Python教程,如有侵权,请告知删除。欢迎与博主一起学习Pythonヽ( ̄▽ ̄)ノ


目录

正则表达式

正则表达式是一种对字符串操作的逻辑公式,也就是记录文本规则的代码。它用一种描述性的语言来给字符串定义一个规则如果字符串符合这个规则,则说明这个字符串时匹配的。

举个例子,我们要判断一个字符串是否为邮箱,那么我们先创建一个匹配邮箱的正则表达式。将这个正则表达式与输入的字符串匹配,如果匹配成功,那么这个字符串就是一个邮箱。

基本字符和语法

首先了解一下正则表达式里面基本的字符描述:

• 元字符

代码 说明 例子
. 匹配换行符以外的所有字符 py. 匹配py3或pya或py!或py1234567
\w 匹配字母或数字或下划线或汉字 py\w 匹配py3或py_或pya或py1234567或pyasd,456
\s 匹配任意空白符,包括空格,制表符(Tab),换行符,中文全角空格等 p\sy 匹配p y或p\ny
\d 匹配数字 \w\w\d 匹配123或a12或ab2
\b 匹配单词的开始或结束 \b\w\d\b 匹配12或a1
^ 匹配字符串的开始 ^\w\w\w\w 匹配abc123
$ 匹配字符串的结束 ^\w\w\w\w$ 匹配abc1

其中\b^$都是用来匹配位置的,如果只有\w,那么只要有字母或数字或下划线或汉字就能匹配,而没有限制多少个。加上\b^$这些匹配位置的字符就能限制匹配对象为一个单词或是一个字符串。

• 限定符

代码/语法 说明 例子
* 重复零次或更多次 \b\d\w*\b 匹配1或1abc
+ 重复一次或更多次 \b\d\w+\b 匹配1a或1abc
? 重复零次或一次 \b\d\w+\b 匹配1或1a
{n} 重复n次 \b\dx{3}\b 匹配1xxx
{n,} 重复n次或更多次 \b\dx{3,}\b 匹配1xxx或1xxxxx
{n,m} 重复n到m次 \b\dx{2,5}\b 匹配1xx或1xxx或1xxxxx

• 常用语法

在介绍了一些基本的字符之后,我们再来看看常用的语法:

  • [ ]可以表示范围,像这样:

[abcde]可以匹配字符abcde里面的其中一个;
[a-z]可以匹配所有的小写字母
[[0-9a-zA-Z\_]]可以匹配一个数字或字母或下划线,相当于\w
[a-zA-Z\\_][0-9a-zA-Z\\_]*可以匹配以字母或下划线开头,后续接任意数字或字母或下划线组成的字符串,也就是Python的合法变量。

  • |可以表示分枝条件,相当于或,像这样:

A|B可以匹配A或B
[a-z]|A可以匹配所有的小写字母或者A

  • 如果我们要匹配一些特殊字符如-,就要用到转义字符\

比如我们要匹配010-12345这样的号码,就要这样写正则表达式:\d{3}\-\d{3,8}

当然在python有强大的r前缀,这样就不用考虑转义的问题了。

re模块

Python提供的re模块,包含了正则表达式的全部功能。

• re.match( )

我们可以通过re.match( )函数来判断一个字符串与正则表达式是否匹配。

函数语法:

re.match(pattern, string, flags=0)

参数说明:

pattern表示匹配的正则表达式
string表示需要匹配的字符串
flags表示标志位,用于控制正则表达式的匹配方式,如是否多行匹配,是否区分大小写等

配合if语句就可以轻松判断,输入的字符串是否与正则表达式相匹配:

import re
if re.match(r'\d{3}-\d{3,8}','010-1234567'):
    print('OK!')
else:
    print('Failed.')

执行结果:

OK!

• re.split( )

re.split( )可以按照能够匹配的子串来切割字符串,相比用固定的字符来切割更灵活。
固定字符切割:

>>> 'a b   c'.split(' ')
['a', 'b', '', '', 'c']

可见按照固定字符空格切割,并不能识别连续的空格。

正则表达式re.split( )切割:

>>> re.split(r'\s+', 'a b   c')
['a', 'b', 'c']

\s+表示匹配子串为一个或任意个空格。这样就可以识别连续的空格了。

还能加上其他字符,进行识别切割:

>>> re.split(r'[\s\,\;]+', 'a,b, c ; d')
['a', 'b', 'c', 'd']

• group( )

通过group( )我们能提取匹配字符串的子串,比如这个正则表达式:^(\d{3})-(\d{3,8})$,分别用()定义了两个组,然后我们即可以通过group( )来提取这两个组的内容,即提取出区号和本地号码:

>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-1234567')
>>> m
<_sre.SRE_Match object; span=(0, 11), match='010-1234567'>
>>> m.group(0)
'010-1234567'
>>> m.group(1)
'010'
>>> m.group(2)
'1234567'

其中group(0)表示原始字符串,group(1)表示第一个子串,group(2)表示第二个子串,以此类推。
也可以用groups( )来返回所有子串:

>>>m.groups()
('010', '1234567') 

贪婪匹配

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符,如:

>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')

正则表达式^(\d+)(0*)$表示匹配以一个或任意多个数字开头,后续接以零个或无数个0组成的字符串,并把前面的数字与后面0分组。

正则匹配默认贪婪匹配,所以第一个分组就把符合规则的所有数字102300匹配进去了,而第二个分组则没有匹配到0。

我们可以手动设置为非贪婪匹配,即匹配尽可能少的字符。把+改成+?+?表示重复一次或多次但尽可能少重复。

>>> re.match(r'^(\d+?)(0*)$', '102300').groups()
('1023', '00')

这样在第一个分组中,匹配符合但尽可能少的数字,在第二个分组中就能匹配到0。

编译

但我们在Python中使用正则表达式时,re模块内部会执行以下操作:

1.编译正则表达式,如果正则表达式本身的字符串不合法,则报错;
2.用编译后的正则表达式去匹配字符串。

所以我们可以预编译正则表达式,当该正则表达式需要匹配多次时,就能提高匹配效率:

>>> import re
# 编译:
>>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
# 使用:
>>> re_telephone.match('010-1234567').groups()
('010', '1234567')
>>> re_telephone.match('010-8086').groups()
('010', '8086')

其中re.compile( )函数用于编译正则表达式,生成Regular Expression对象,然后调用对应的方法时不用再给出正则表达式。

小结

正则表达式的内容十分多,本节内容仅供初步了解。如果常用到正则表达式,那么需要有一份正则表达式语法参考手册来参考使用。

想要了解更多的正则表达式内容,推荐学习:正则表达式30分钟入门教程


以上就是本节的全部内容,感谢你的阅读。

下一节内容:常用内建模块介绍

有任何问题与想法,欢迎评论与吐槽。

和博主一起学习Python吧( ̄▽ ̄)~*

猜你喜欢

转载自blog.csdn.net/lecorn/article/details/81943444