正则表达式与Python常用模块 -- re模块常用用法
正则表达式
到底什么是正则表达式?
在编写处理字符串的程序或网页时,经常有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
常用元字符
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
a|b | 匹配字符a或字符b |
() | 匹配括号内的表达式,也表示一个组 |
[...] | 匹配字符组中的字符 |
[^...] | 匹配除了字符组中字符的所有字符 |
示例
正则表达式模式 | 匹配的字符串 |
---|---|
\w+-\d+ |
一个由字母数字组成的字符串和一串由一个连字符分割的数字 |
[A-Za-z]\w* |
第一个字符是字母;其余字符(如果存在)可以是字母或数字(几乎等价于Python中的有效标识符) |
\d{3}-\d{d}-\d{4} |
美国电话号码的格式,前面是区号前缀,例如:800-555-1212 |
\w+@\w+\.com |
以 XXX@YYY.com 格式表示的简单电子邮件地址 |
常用限定符
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次(更多次优先) |
+ | 重复一次或更多次(更多次优先) |
? | 重复零次或一次(一次优先) |
重复n次 | |
重复n次或更多次 | |
重复n到m次 |
示例
正则表达式 | 匹配的字符串 |
---|---|
(\w)*world |
helloworld worldworld world |
(\w)+world |
helloworld worldworld |
(\w)?world |
oworld world |
常用反义词
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
字符组[]
在同一位置可能出现的字符组成了一个字符组,在正则表达式中用[]
表示
正则 | 待匹配字符 | 匹配结果 | 说明 |
---|---|---|---|
[0123456789] |
8 |
True |
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符和"待匹配字符"相同都视为可以匹配 |
[0123456789] |
a |
False |
由于字符组中没有"a"字符,所以不能匹配 |
[0-9] |
7 |
True |
也可以用-表示范围,[0-9]就和[0123456789]是一个意思 |
[a-z] |
s |
True |
同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示 |
[A-Z] |
B |
True |
[A-Z]就表示所有的大写字母 |
[0-9a-fA-F] |
e |
True |
可以匹配数字,大小写形式的a~f,用来验证十六进制字符 |
使用圆括号制定分组
一对圆括号可以实现以下任意一个(或者两个)功能
- 对正则表达式进行分组
- 匹配子组
正则表达式模式 | 匹配的字符串 |
---|---|
\d+(\.\d*)? |
表示简单浮点数的字符串:也就是说,任何十进制数字,后面可以接一个小数点和零个或者多个十进制数字,例如0.004 、2 、75. 等 |
(Mr?s?\.)?[A-Z][a-z]*[A-Za-z]+ |
名字和姓氏,以及对名字的限制(如果有,首字母必须大写,后续字母小写),全名前可以有可选的Mr. 、Mrs. 、Ms. 或者M. 作为称谓,以及灵活可选的姓氏,可以有多个单词、横线以及大写字母 |
贪婪模式
贪婪模式
贪婪模式:在满足匹配规则时,匹配尽可能长的字符串
?+*
默认都是贪婪模式。
非贪婪模式
非贪婪模式:在满足匹配规则时,匹配尽可能短的字符串
+*
使用?
变成非贪婪模式
几个常用的非贪婪匹配pattern
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复
.*?
的用法
. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
何在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x
就是取前面任意长度的字符,直到一个x出现
扩展表示法
它们是以问号开始(?...)
。我们不会为此花费太多时间,因为它们通常用于在判断匹配之前提供标记,实现一个前视(或者后视)匹配,或者条件检查。
re模块常用用法
"""
re 模块使 Python 语言拥有全部的正则表达式功能。
"""
import re
pattern = 'o'
pattern1 = 'a'
content = 'hello world'
"""
findall
返回所有满足匹配条件的结果,放在列表里
"""
ret = re.findall(pattern, content)
print(ret)
"""
search
在字符串内找到第一个匹配然后返回一个包含匹配信息的对象(如果字符串没有匹配,则返回None),该对象通过group()方法得到匹配的字符串。
match
从字符串开头处开始匹配
找到第一个匹配然后返回一个包含匹配信息的对象(如果字符串没有匹配,则返回None),该对象通过group()方法得到匹配的字符串。
group groups 补充
ret.group() 完整匹配
ret.group(1) 子组1
ret.groups() 全部子组(元祖类型)
"""
ret = re.search(pattern, content)
print(ret.group())
ret = re.match('he', content)
print(ret.group())
"""
split
基于正则表达式的模式分割字符串,并返回一个列表
"""
# 示例1
ret = re.split(pattern, content)
print(ret) # ['hell', ' w', 'rld']
# 示例2
ret2 = re.split('[ac]', 'abcdef')
print('ret2', ret2) # ret2 ['', 'b', 'def'] 先按a切割得到''和'bcdef', 再按c切割得到'' 'b' 'def'
"""
sub()和subn()
两者几乎一样,都是将某字符串中所有匹配正则表达式的部分进行某种形式的替换。
替换的部分通常是一个`字符串`,但它也可能是一个`函数`,该函数返回一个用来替换的字符串。
区别:subn()和sub()功能一样,但subn()还返回一个表示替换的总数,`替换后的字符串`和表示`替换总数`的数字作为一个拥有两个元素的元祖返回。
"""
print(re.sub('X', 'Mr.smith', 'attn:X\n\nDear X, \nHow U Doing'))
print(re.sub('[ae]', 'X', 'abcdef')) # XbcdXf
print(re.subn('[ae]', 'X', 'abcdef')) # ('XbcdXf', 2)
"""
finditer()
finditer返回一个存放匹配结果的迭代器
"""
ret = re.finditer('\d', 'ds3sy4784a')
print(next(ret).group()) # 查看第一个结果
print(next(ret).group()) # 查看第二个结果
print([i.group() for i in ret]) # 查看剩余的匹配结果
"""
compile
将正则表达式编译成为一个 正则表达式对象
"""
obj = re.compile('\d{3}')
ret = obj.findall('abc123def888')
print(ret)
"""
注意
findall和split的优先级问题
1,findall时,如果正则表达式有启用`分组`,则会优先把匹配结果分组里内容返回.如果想要匹配结果,取消权限即可
2,split时,没有()的没有保留所匹配的项,但是有()的却能够保留匹配的项
"""
print(re.findall('www\.(google|baidu)\.com', 'www.google.com')) # ['google']
print(re.findall('www\.(?:google|baidu)\.com', 'www.google.com')) # hello world) # ['www.google.com']
print(re.split("\d+", "google3facebook4twitter")) # ['google', 'facebook', 'twitter']
print(re.split("(\d+)", "google3facebook4twitter")) # ['google', '3', 'facebook', '4', 'twitter']