十、正则表达式
设计思想:用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的
- \d :匹配一个数字; \w :匹配一个字母或数字; \s :匹配一个空格(也包括Tab等空白符)
- . :匹配任意字符; * :表示任意个字符(包括0个); + :表示至少一个字符; ? :表示0个或1个字符;
- {n} :表示n个字符; {n,m} :表示n-m个字符; '-' :是特殊字符,要用 '\' 转义; [] :表示范围;
- [0-9a-zA-Z\_] :可以匹配一个数字、字母或者下划线;
- [0-9a-zA-Z\_]+ :可以匹配至少由一个数字、字母或者下划线组成的字符串;
- [a-zA-Z\_][0-9a-zA-Z\_]{0, 19} :更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)
-
A|B 可以匹配A或B,所以 (P|p)ython 可以匹配 'Python' 或者 'python' 。
-
^ 表示行的开头, ^\d 表示必须以数字开头。
-
$ 表示行的结束, \d$ 表示必须以数字结束。
- re模块:包含所有正则表达式的功能
1 import re 2 s = re.match(r'^\d{3}\-\d{3,8}$','010-12345') 3 print(s) 4 5 输出: 6 #返回一个match对象 7 <re.Match object; span=(0, 9), match='010-12345'>
match() 方法判断是否匹配,如果匹配成功,返回一个 Match 对象,否则返回 None 。常见的判断方法:
1 import re 2 test = '用户输入的字符串' 3 if re.match(r'正则表达式',test): 4 print('OK!') 5 else: 6 print('Failed!')
- 切分字符串:用正则表达式来把不规范的输入转化成正确的数组。
1 import re 2 print(re.split(r'\s+','a b c')) #至少一个空格 3 print(re.split(r'[\s\,]+','a,b, c')) #至少一个[]里的内容,即空格与逗号; 4 print(re.split(r'[\s\,\;]+','a,b;; c')) 5 6 输出: 7 ['a', 'b', 'c'] 8 ['a', 'b', 'c'] 9 ['a', 'b', 'c']
- 分组:用 () 表示的就是要提取的分组(Group),可以在 Match 对象上用 group() 方法提取出子串来
1 import re 2 m = re.match(r'^(\d{3})-(\d{3,8}$)','010-12345') 3 x1 = m.group(0) 4 x2 = m.group(1) 5 x3 = m.group(2) 6 print(m) 7 print(x1,x2,x3) 8 9 输出: 10 <re.Match object; span=(0, 9), match='010-12345'> 11 010-12345 010 12345
group(0) 永远是原始字符串, group(1) 、 group(2) ……表示第1、2、……个子串。
- 贪婪匹配:正则匹配默认是贪婪匹配,即匹配尽可能多的字符
1 import re 2 m1 = re.match(r'^(\d+)(0*)$','102300').groups() 3 m2 = re.match(r'^(\d+?)(0*)$','102300').groups() 4 print(m1) 5 print(m2) 6 7 输出: 8 ('102300', '') 9 ('1023', '00')
\d+采用贪婪匹配,直接把后面的
0
全部匹配了,结果0*只能匹配空字符串了。须让\d+采用非贪婪匹配(也就是尽可能少匹配),加? =》 \d+?才能把后面的0匹配出来。
编译:
- 在Python中使用正则表达式时,re模块内部会干两件事情:
- 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
- 用编译后的正则表达式去匹配字符串。
- 对于需要重复多次的正则表达式,出于效率的考虑,可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:
1 import re 2 #编译,re_relephone为赋予的变量 3 re_telephone = re.compile(r'^(\d{3})-(\d{3,8}$)') 4 m1 = re_telephone.match('010-12345').groups() 5 m2 = re_telephone.match('020-54321').groups() 6 print(m1,m2) 7 8 输出: 9 ('010', '12345') ('020', '54321')
编译后生成Regular Expression对象,由于该对象自己包含了正则表达式,所以调用对应的方法时不用给出正则字符串。