概述:
相关函数(说明与测试结果):
关于?的更多用法:
正则表达式是一些由字母、数字与特殊的符号组成的字符串,描述了这些字符与字符之间的某种重复的方式,可以用来通过匹配寻找一些有相似特征的字符串的集合。正是因为这种特性,在文本搜索中有着广泛的应用。
Python中,使用re模块来支持正则表达式。在Python中,模式匹配(pattern matching)又细分为:搜索(searching)与匹配(matching)。区别主要是:搜索通过search()函数实现,可以在字符串的任意位置开始查找要匹配的模式;匹配使用match()函数,用来判断一个字符串是否可以从头全部或者部分匹配某个模式。
最简单的,可以使用26个大小写字母与数字组成最简单的正则表达式,但这种正则表达式是没有多大用处的,就像在一个文本中查找某个单词一样简单,完全体现不出正则表达式的优势。所以使用特殊字符才是正则表达式的精髓。
特殊符号可以定义字符的集合,子组匹配,模式重复次数,以达到匹配字符串集合而非单个字符串的目的。
常用正则表达式符号:
literal # 匹配字符串的值:abc
re1|re2 #匹配正则表达式1或者2:abc|xyz
. #匹配任意一个字符(除了换行符)(必须有,不能为空):a.c
^ #标记一个字符串的开始:^bc表示在以bc开始的字符串中寻找bc
$ #标记一个字符串的结束:ab$表示在以ab结尾的字符串中寻找ab
* #匹配前面出现的正则表达式0次或多次,优先匹配长度最长的,贪心策略,等价于{0,}:[A-Za-z0-9]*
+ #匹配前面出现的正则表达式1次或多次,优先匹配长度最长的,贪心策略,等价于{1,}:[A-Za-z0-9]+
? #匹配前面出现的正则表达式0次或1次,也可以接在*+{}之后,表示优先匹配长度最短的,为后面的模式留下更多的字符:[A-Za-z0-9]?
{N} #匹配前面出现的正则表达式N次:[A-Za-z0-9]{2}
{N,} #至少匹配N次
{M,N} #匹配前面出现的正则表达式M-N次,从长往短匹配,重复N次未找到才会依次减少重复次数继续匹配:[A-Za-z0-9]{1,3}
[...] #匹配[]中出现的任意一个字符:[abc]
[...x-y...] #针对x-y,是匹配从x-y中的任意一个字符:[A-Za-z0-9]
[^...] #不匹配^之后出现的任何一个字符,包括x-y这种某一范围的字符:[^A-Z0a-z]不匹配A-Z,0,a-z中的任何一个字符
(...) 匹配()中的正则表达式,并将其视为一体,与数学中加()作用相似:([A-Z]{2})?[0-9]与[A-Z][A-Z][0-9]|[0-9]等价
#特殊字符
\d #匹配任意一个数字,与[0-9]等价:func\d+.py
\D #与\d相反,匹配任意一个非数字,与[^0-9]等价
\w #匹配任意一个数字或者英文字母,与[A-Za-z0-9]等价:\wbc
\W #与\w相反,等价于[^A-Za-z0-9]
\s #匹配任意一个空白符,与[ \n\t\r\v\f]相同:a\sstring
\S #与\s相反
\b #匹配单词边界,与\B反义:\bstring\b
\nn #匹配已保存的子组(...)
\c #取消字符c的特殊意义,按其字面意义匹配:\? \+ \* \. \\
#\A #匹配字符串的开始,与^等价:\Astring
#\Z #匹配字符串的结束,与$等价:string\Z
相关函数(说明与测试结果):
re.match(pattern,string) #在string中match pattern,必须从string开头开始match,返回匹配的字符串或者None。可以使用group()得到这个返回值
>>> result=re.match('t.+?','this is a string')
>>> if result is not None:
result.group()
'th'
re.search(pattern, string) #在string中search pattern,从string的任何位置都可以开始search,返回匹配的字符串或者None。可以使用group()得到这个返回值
>>> result=re.search('s[^ ]+?','this is a string')
>>> if result is not None:
result.group()
'st'
# 除了group()之外,还有groups()函数,用来获得一个元组,这个元组由匹配到的字符串中对应pattern的所有子组的字符构成(一个子组是元组中的一项):
>>> result=re.search('(\w\w\w)-(\d\d\d)','abcxyz-1234')
>>> result.group() #参数默认值为0,表示返回匹配到的整个字符串
'xyz-123'
>>> result.group(1) #group()函数也可用来获得单个子组,如果没有这个子组,则报错
'xyz'
>>> result.group(2)
'123'
>>> result.groups() #groups()参数对结果没有影响,都是列出所有子组,相当于将group()函数的参数从1开始一直到子组数目上限处的返回值组合成一个元组,若无子组,则返回空的元组
('xyz', '123')
>>> result.group(0)
'xyz-123'
#另外,子组也可以嵌套,如(x(y)),则xy表示第一个子组,y表示第二个子组
re.findall(pattern, string) #找到string中所有可以匹配pattern的字符串,并通过一个list返回。
>>> result=re.findall('.s','This is a string.')
>>> result
['is', 'is', ' s']
>>> re.findall('(\w\w\w)-(\d\d\d)','abc-123,bcd-234,fdd-213')
[('abc', '123'), ('bcd', '234'), ('fdd', '213')] #有子组时,返回的是由子组构成的元组
re.sub(old_substring, new_substring, original_string) #搜索与替换。在original_string中搜索old_substring(old_substring其实是pattern),并把搜索到的所有old_substring替换为new_substring(new_substring中即便有特殊字符,也不会当成是正则表达式来处理,视为一般的字符)
>>> re.sub('[xyz]','XYZ','axbycz') #返回替换后的字符串
'aXYZbXYZcXYZ'
>>> re.subn('[xyz]','XYZ','axbycz') #返回一个元组,由替换后的字符串与替换次数组成
('aXYZbXYZcXYZ', 3)
re.split(pattern, string) #使用pattern分割string,与字符串中的split()函数功能类似,只是后者不能处理正则表达式的特殊字符,如果前者没有使用特殊字符,则与后者完全相同
关于?的更多用法:
#关于?,还有一些组合用法:(?:pattern), (?=pattern), (?!pattern), (?<=pattern), (?<!pattern)
>>> result=re.search('Windows(?:95|98|NT|2000)','Windows2000') #匹配(?:...)中的pattern,并获得。(但百度百科上说不获得,不知道是不是Python自己改的)(没看出来跟把?:直接去掉有什么区别)
>>> result.group()
'Windows2000'
>>> result=re.search('Windows(?=95|98|NT|2000)','Windows2000') #正向匹配(?=...)中的pattern,即判断的是()前的字符串,如果存在则匹配上,但不获得。
>>> result.group()
'Windows'
>>> result=re.search('Windows(?!95|98|NT|2000)','Windowsxp') #与(?=...)相反,正向匹配(?!...)中的pattern,即判断的是()前的字符串,如果不存在则匹配上,但不获得。
>>> result.group()
'Windows'
#(?<=pattern), (?<!pattern)分别与(?=pattern), (?!pattern)相反,是反向匹配。