正则表达式
1.导入re模块:import re
import re # 将正则表达式编译成Pattern对象 pattern = re.compile(r'hello') #compile(pattern对象,[匹配模式]),pattern即正则表达式,匹配模式下次再扩充 # 使用Pattern匹配文本,获得匹配结果,无法匹配时将返回None match = pattern.match('hello world!') #match(匹配的文本),也可以直接re.match('pattern对象','匹配的文本'),将前面的pattern上面的句子结合在一起 if match: # 使用Match获得分组信息 print match.group() ### 输出 ### # hello
扩展:
search(),match(),findall()区别
match():判断从开始位置是否匹配,如果匹配成功,则返回Match对象,若果匹配不成功则返回None
search():从整体匹配,返回第一个匹配的字符
findall():从整体匹配,返回所有匹配的字符,以列表的形式
>>> pattern=re.compile(r'hi') >>> match=pattern.match('kkk,hi,history') #开始位置为kkk,不是所要匹配的字符hi >>> if match: print match.group() #match()从开始位置匹配hi,若不匹配,返回None,即为空 >>> pattern=re.compile(r'hi') >>> match=pattern.search('kkk,hi,history') #从整体匹配,返回所第一个匹配的字符 >>> if match: print match.group() hi >>> pattern=re.compile('wh') >>> match=pattern.findall('where,what,which,why,who are you,wheeuuy') >>> print match ['wh', 'wh', 'wh', 'wh', 'wh', 'wh'] #以列表形式返回所有匹配的字符
2.匹配字符
注意:
(1)特殊字符需要用‘’转义,例如‘-’,匹配时为:‘-’
(2)():分组匹配;{}:制定长度;[]:范围
(3)?的用法
- 原文符号:?
- 作为数量词:?匹配0或一个字符
- 非贪婪匹配
- *? 重复任意次,但尽可能少重复
- +? 重复1次或更多次,但尽可能少重复
- ?? 重复0次或1次,但尽可能少重复
- {n,m}? 重复n到m次,但尽可能少重复
- {n,}? 重复n次以上,但尽可能少重复
4.不捕捉模式
语法 |
说明
|
实例
|
(pattern) |
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“(”或“)”。
|
|
(?:pattern)
|
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。
|
例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
|
(?=pattern)
|
非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。
|
例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
|
(?!pattern)
|
非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。
|
例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
|
(?<=pattern)
|
非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。
|
例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
|
(?<!pattern)
|
非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。
此处用或任意一项都不能超过2位,如“(?<!95|98|NT|20)Windows正确,“(?<!95|980|NT|20)Windows 报错,若是单独使用则无限制,如(?<!2000)Windows 正确匹配
|
例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题
|
表1:预定义字符集,可用在字符集[]中,如[d]
语法 | 说明 |
d | 一个数字 |
D | 非数字 |
w | 一个字母或数字 |
W | 特殊字符 |
s | 空白字符,换行符,空白符,制表符等 |
S | 非空白字符 |
表2:数量词,不代表字符和位置,而是制定前边的字符的匹配数量,可用在字符或(....)之后,如()?
语法 | 说明 |
. | 任意一个字符,除换行符外 |
* | 任意可变长字符(包括0个) |
+ | 一个字符或多个 |
? | 0或一个字符 |
{n} | 重复n次 |
{n,} | 重复n次或大于n次 |
{n,m} | 重复n-m次 |
表3:边界匹配
边界:边界指的是一个位置,而不是一个字符
例如:bakhihi a hdkskjdksa - hhdksjdkj-hdkjdkj
如果我们想匹配a,但不想从其他单词中匹配,只想单独匹配,a即可匹配,若要匹配非单词的-,同样B-B
语法 | 说明 |
^x | 行以x开头,多行时匹配每一行开头 |
A | 仅字符串开头 |
y$ | 行以y结尾,多行匹配每一行的结尾 |
仅字符串结尾 | |
单词边界匹配,单词的分界线 | |
B | 非单词匹配 |
表4:逻辑,分组
语法 | 说明 | 实例 | 结果 |
A|B | A或B | a|b | a或b皆可匹配 |
() | 分组 | ^(d{3})-(d{3,8})$ |
123-456789 |
分组:
例如: ^(d{3})-(d{3,8})$
由两个()组成,匹配两个组,可以通过group()取值
>>> m = re.match(r'^(d{3})-(d{3,8})$', '010-12345') >>> m <_sre.SRE_Match object; span=(0, 9), match='010-12345'> #如果正则表达式中定义了组,就可以在Match
对象上用group()
方法提取出子串来 >>> m.group(0) #group(0):指取整个字符串 '010-12345' >>> m.group(1) #group(1):取第一个分组的内容 '010' >>> m.group(2) #group(2):取第二个分组的内容 '12345'
3.理解贪婪匹配和非贪婪匹配
正则表达式默认是贪婪匹配,即匹配尽可能多的字符。
非贪婪匹配可以使用?,让其尽可能少匹配,见上面?的用法的非贪婪匹配。
例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"