正则表达式与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.004275.
(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']

posted @ 2020-03-04 16:59  孙昌恒  阅读(153)  评论(0编辑  收藏  举报