字符串 是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。正则表达式是一种用来匹配字符串的强有力的武器。
正则表达式的设计思想:是用一种描述性的语言来给字符串定义一个法则,凡是符合规则的字符串,就认定它“匹配”了,否则该字符串就是不合法的。
判断一个字符串是否合法的Email的方法:
正则表达式中,直接给出字符就是精确匹配。
表达式 | 说明 | 举例 |
---|---|---|
0 | 匹配数字0,两个0 则匹配两个数字0 |
0 |
\d | 0-9的一个数字 | 1或2或3 |
\w | 一个字母或数字 | 0或a或B |
. | 任意一个字符 | c或0或!或#等等 |
* | 匹配任意个字符(包括0个) | 略 |
+ | 至少一个字符 | 略 |
? | 0个或1个字符 | 略 |
{n} | n个字符,用{n,m} 表示n-m个字符 |
略 |
\d{3} | 匹配3个数字 | 010 或124 等 |
\s | 匹配一个空格(包括Tab等空白符) | ' ' |
\s+ | 匹配至少有一个空格 | 例如匹配' ' 、' ' 等 |
\d{3,8} | 匹配3-8个数字 | 1234567 |
010-12345
:-
是特殊字符,在正则表达式中用'\'
转义,所以应该是\d{3}\-\d{3,8}
做更精确的匹配,可用[]
表示范围:
[0-9a-zA-Z\_]
:匹配一个数字、字母或下划线[0-9a-zA-Z\_]+
:匹配至少由一个数字、字母或下划线组成的字符串,比如'a100'
、''0_Z'
、'Py3000'
等[a-zA-Z\_][0-9a-zA-Z\_]*
:可匹配由字母、数字或下划线开头,后接任意个由一个数字、字母或下划线组成的字符串,也就是Python合法的变量[a-zA-Z\_][0-9a-zA-Z\_]{0,19}
更精确的限制了变量的长度是1-20个字符(前面一个字符+后面最多19个字符)表达式 | 说明 | 举例 |
---|---|---|
| |
逻辑关系“或” | A|B 匹配A 或B ,(P|p)ython 可匹配'Python' 或'python' |
^ |
行的开头 | ^\d 表示必须以数字开头 |
$ |
行的结束 | \d$表示必须以数字结束。 py可匹配 ’hpy’或 ‘pyt’,但加上 ^py$就只能匹配 ‘py’` |
Python的re模块包含所有正则表达式的功能
Python的字符串本身也用\
转义,所以需要注意,但字符串前加r
就不用考虑转义的问题了:r'abc'
。
match()
方法判断是否匹配,匹配成功返回一个Match
对象,否则返回None
:
>>> import re
>>> re.match(r'\d{3}\-\d{3,8}$','010-12345') # 成功示例
.Match object; span=(0, 9), match='010-12345'>
>>> re.match(r'\d{3}\-\d{3,8}$','010 12345') # 失败示例
>>>
用正则表达式切分字符串比用固定的字符更灵活。
语法:re.split(r'表达式',字符串)
>>> 'a b c'.split(' ')
['a', 'b', '', 'c']
\s+
匹配至少一个空格(可以识别连续空格):>>> re.split(r'\s+','a b c')
['a', 'b', 'c']
,
:>>> re.split(r'[\s\,]+','a,b, c d')
['a', 'b', 'c', 'd']
,
和;
:>>> re.split(r'[\s\,\;]+','a,b; c d')
['a', 'b', 'c', 'd']
如果用户输入一组标签,可用正则表达式把不规范的输入转化成正确的列表。
正则表达式除判断是否匹配外还有提取子串的强大功能。用()
表示要提取的分组(Group)。比如^(\d{3})-(\d{3,8})$
分别定义了两个组,可直接从匹配的字符串中提取出区号和本地号码:
>>> m = re.match(r'^(\d{3})-(\d{3,8})$','010-12345')
>>> m
.Match object; span=(0, 9), match='010-12345'>
>>> m.group(0)
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'
>>> m.group(3)
Traceback (most recent call last):
File "" , line 1, in
IndexError: no such group
上边的例子中设置了两个组,在Match
对象上用group()
方法提取子串:
group(0)
或group()
是原始字符串group(1)
是第1个子串,group(2)
是第2个子串,超出范围报错re.match().groups()
会以元组形式返回组信息正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。
demo:匹配出数字后面的0
:
>>> re.match(r'^(\d+)(0*)$','102300').groups()
('102300', '')
\d+
采用贪婪匹配,直接把后面的0
全部匹配了,结果0*
只能匹配空字符串了。\d+
采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0
匹配出来,加个?
就可以让\d+
采用非贪婪匹配:>>> re.match(r'^(\d+?)(0*)$','102300').groups()
('1023', '00')
Python使用正则表达式时,re
模块内部会干两件事:
如果一个正则表达式要重复使用几千次,出于效率的考虑,可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:
>>> re_telephone.match('010-12345').groups()
('010', '12345')
>>> re_telephone.match('010-9527').groups()
('010', '9527')
编译后生成Regular Expression对象,该对象自己包含正则表达式,所以调用对应方法时不用给出正则表达式。