五、正则表达式

正则表达式(Regular Express)的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
\d可以匹配一个数字,\w可以匹配一个字母或数字,\s可以匹配一个空格,.可以匹配任意字符,要匹配边长字符,用*表示任意个字符(包括零个),+表示至少一个字符,?表示0个或者1个字符,{n}表示n个字符,用{m,n}表示m-n个字符,比如:
\d{3}\s+\d{3,8}表示匹配3个数字,至少匹配一个空格,匹配3-8个数字。

精确匹配

要做精确匹配,可以使用[]来表示范围:
[0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线。
[0-9a-zA-Z\_]+可以匹配至少有一个数字、字母或者下划线组成的字符串。
[a-zA-Z\_][0-9a-zA-Z\_]+可以匹配由字母或者下划线开头,后接任意一个数字、字母、下划线组成的字符串。
[a-zA-Z\_][0-9a-zA-Z\_]{1, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
A|B可以匹配AB,所以(P|p)ython可以匹配'Python'或者'python'^表示行的开头,^\d表示必须以数字开头。$表示行的结束,\d$表示必须以数字结束。

re模块
re模块包含了所有的正则表达式的功能,建议使用r前缀来避免转义r'abc\-001',没有r前缀就得进行转义abc\\-001

1
2
3
import re
result = re.match(r'^\d{3}\-\d{3,8}', '010-123456')
print(result)

match()方法判断是否匹配,如果匹配成功返回Match对象,否则返回None

1
2
3
4
5
6
7
import re
test = input('请输入字符串')
regx = r'正则表达式'
if re.match(regx, test):
print('ok')
else:
print('failed')

切分字符串
使用正则表达式能够更加灵活的切分字符串。

1
2
3
4
5
import re
'ab c'.split(' ') # [a, b, , , c] 传统的切分无法识别空格
re.split(r'\s+', 'ab c') # [a, b, c] 正则表达式能够识别空格
re.split(r'[\s\,]+', 'a,b,, ,c') # [a, b, c]
re.split(r'[\s\,\;]+', 'a;b,c; ;') # [a, b, c]

分组

正则表达式采用()来表示分组。

1
2
3
4
5
import re
m = re.match(r'^(\d{3})-(\d{3,8})$', '010-123456')
m.group(0) # '010-123456'
m.group(1) # '010'
m.group(2) # '123456'

贪婪匹配

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

1
2
import re
m = re.match(r'^(\d+)(0*)$', '102300').groups() # ('102300', '')

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

1
2
import re
m = re.match(r'^(\d+?)(0*)$', '102300').groups() # ('1023', '00')

编译

当我们在Python中使用正则表达式时,re模块内部会干两件事情:

  • 编译正则表达式,如果正则表达式的字符串本身不合法,会报错。
  • 用编译后的正则表达式去匹配字符串。
    如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:
1
2
3
import re
pre_compile = re.compile(r'^(\d{3})-(\d{3,8})$') # 进行编译
pre_compile.match('010-12345').groups() # 使用

正则表达式详细参考:python正则表达式