PS:字符串是编程时涉及到的最多的一种数据结构,对字符串的操作几乎无处不在。 正则表达式就是处理字符串最好的方法。
参考原文
定义
正则表达式是一种用来匹配字符串的强有力的武器,它的设计思想是用一种描述性的语言来给字符串定义一个规则凡是符合规则的字符串,我们就认为它“匹配”,否则,不匹配。
规则
\d 可以匹配一个数字,\w 可以匹配一个数字或字母,\s 可以匹配一个空格(包括TAB等空白符). 匹配任意一个字符,* 匹配任意个字符(包括0个),+ 匹配至少一个字符,?表示0个或1个字符,{n} 表示匹配n个字符, {
n-m}表示匹配n到m个字符。更精确地匹配,可以用 [ ] 表示范围,如:[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个字符(前面1个字符+后面最多19个字符)。A|B可以匹配A或B;^表示行的开头,^\d表示以一个数字开头,$ 表示行的结束,\d$表示必须以数字结尾。
Tip:要匹配特殊字符如 '-'就需要使用'\'转义。
re(regular expression)模块
OK,说清楚了基本的规则后,我们就来看看怎么在Python中使用regex,Python中提供了re模块,该模块包含了
所有正则表达式的功能。
注意:要注意一点Python的字符串本身也用 \ 转义,所以我们应该使用r前缀来使我们不必考虑字符串本身的转义问题。
说了这么多,我们来看看怎么在Python匹配字符串:
>>> import re>>> re.match(r'^\d{3}\-\d{3,8}$', '010-12345')<_sre.SRE_Match object; span=(0, 9), match='010-12345'>>>> re.match(r'^\d{3}\-\d{3,8}$', '010 12345')>>>
match()方法匹配时,成功返回一个Match对象,失败返回None。常见的判断方法:
test = '用户输入的字符串'if re.match(r'正则表达式', test): print('ok')else: print('failed')
切分字符串
用正则表达式切分字符串比用固定的字符更灵活,为什么?请看正常的切分代码:
>>> 'a b c'.split(' ')['a', 'b', '', 'c']
无法识别连续的空格,此时想到Regex,来试试:
>>> re.split(r'\s+', 'a b c')['a', 'b', 'c']
加入, 试下:
>>> re.split(r'[\s\,]+', 'a,b,c ,d')['a', 'b', 'c', 'd']
Tips:如果用户输入了一组标签,记得用正则表达式来把不规范的输入转化成正确的数组。
分组
除了简单地判断是否匹配外,正则表达式还有提取子串的强大功能。用() 表示的就是要提取的分组,如:^(\d{3})-(\d{3,8})$分别定义了两个分组,这就可以直接从匹配的字符串中提取出区号和本地号码:
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')>>> m<_sre.SRE_Match object; span=(0, 9), match='010-12345'>>>> m.group(0)'010-12345'>>> m.group(1)'010'>>> m.group(2)'12345
注意:group(0)永远是原始字符串,group(1),group(2)......表示第1,2.....个子串。
贪婪匹配
正则表达式默认是贪婪匹配,也就是匹配尽可能多的字符。如,匹配数字后面的0:
>>> re.match(r'^(\d+)(0*)$', '102300').groups()('102300', '')
可见\d+采用贪婪匹配使后面的0*只能匹配空字符串了。
那么怎么让\d+采用非贪婪匹配(尽可能少地匹配),让后面的0*也能匹配到字符,加个?就可以了:
>>> re.match(r'^(\d+?)(0*)$', '102300').groups()('1023', '00')
Tips:groups()所有分组后的子串,不包括原始字符串。当我们在Python中使用正则表达式时,如果一个正则表达式要使用几千次,我们就可以预编译该正则表达式,接下来就不需要编译了,直接匹配,这样可以提高效率。