正则表达式介绍
正则表达式的常用符号
python的re模块
findall()函数
finditer()函数
match()函数
search()函数
split()函数
Python 通过标准库中的 re 模块来支持正则表达式。
正则表达式作为高级的文本模式匹配、抽取、和搜索。简单地说,正则表达式(简称为 regex)是一些由字符和特殊符号组成的字符串,按照设定的匹配逻辑能够匹配一系列有相似特征的字符串。
举例:re模块的findall函数在大量的文本信息中找到“3位区号-7位数字”的固定电话号码。
sr = '足看025-2322222,呢023-32322,噢00哦30哦0290231312312' * 5
print(re.findall('\d{3}-\d{7}',sr))
打印结果如下:找到了5个号码
['025-2322222', '025-2322222', '025-2322222', '025-2322222', '025-2322222']
常用到到的表达式符号如下,将不同的符号组合为正则表达式
符号 |
解释 |
示例 |
re1|re2 |
匹配正则表达式 re1 或者 re2 |
foo|bar |
. |
匹配任何字符(除了\n 之外) |
b.b |
^ |
匹配字符串起始部分 |
^Dear |
$ |
匹配字符串终止部分 |
/bin/*sh$ |
* |
匹配 0 次或者多次前面出现的正则表达式 |
[A-Za-z0-9]* |
+ |
匹配 1 次或者多次前面出现的正则表达式 |
[a-z]+\.com |
? |
匹配 0 次或者 1 次前面出现的正则表达式 |
goo? |
{N} |
匹配 N 次前面出现的正则表达式 |
[0-9]{3} |
{M,N} |
匹配 M~N 次前面出现的正则表达式 |
[0-9]{5,9} |
[…] |
匹配来自字符集的任意单一字符 |
[aeiou] |
[..x−y..] |
匹配 x~y 范围中的任意单一字符 |
[0-9], [A-Za-z] |
[^…] |
不匹配此字符集中出现的任何一个字符,包括某一范围的字符(如果在此字符集中出现) |
[^aeiou], [^A-Za-z0-9] |
(*|+|?|{})? |
用于匹配上面频繁出现/重复出现符号的非贪婪版本(*、+、?、{}) |
.*?[a-z] |
(…) |
匹配封闭的正则表达式,然后另存为子组 |
([0-9]{3})?,f(oo| |
\d |
匹配任何十进制数字,与[0-9]一致(\D 与\d 相反,不匹配任何非数值型的数字) |
data\d+.txt |
\w |
匹配任何字母数字字符,与[A-Za-z0-9_]相同(\W 与之相反) |
[A-Za-z_]\w+ |
\s |
匹配任何空格字符,与[\n\t\r\v\f]相同(\S 与之相反) |
of\sthe |
\b |
匹配任何单词边界(\B 与之相反) |
\bThe\b |
\N |
匹配已保存的子组 N(参见上面的(…)) |
price: \16 |
\c |
逐字匹配任何特殊字符 c(即,仅按照字面意义匹配,不匹配特殊含义) |
\., \\, \* |
\A(\Z) |
匹配字符串的起始(结束)(另见上面介绍的^和$) |
\ADear |
举几个例子:
1 匹配以字母a开头,以字母b结束的中间为任意1个数字
表达式=’^a[0-9]b$’
sr2 = 'a2b'
sr3='acb'
print(re.findall('^a[0-9]b$',sr2))
print(re.findall('^a[0-9]b$',sr3))
#打印结果 字符串sr2符合要求
['a2b']
[]
2 匹配字母s或者字母c出现1到3次
表达式='[s|c]{1,3}'
sr4 = 'a2bsbccs233scacss'
print(re.findall('[s|c]{1,3}',sr4))
3 匹配字母c和f之前的任意字符
表达式=‘c.*f’
sr5='acdfdfb'
print(re.findall('c.*f',sr5))
打印结果:
['cdfdf']
安装完python后通过import re直接导入使用
re常用函数有match(),search(),findall(),finditer(),split()
findall()函数匹配正则表达式,匹配所有符合条件的数据,并返回一个列表,匹配不上返回为空列表,上面已经有举例,不在次多做介绍。
finditer()函数与 findall()函数相同,但返回的不是一个列表,而是一个迭代器。对于每一次匹配,迭代器都返回一个match匹配对象
sr = '看025-2322222,设定023-32322,噢00哦30哦0290231312312'
#打印匹配的结果
print(re.finditer('\d{3}-\d{7}',sr))
#打印list()函数将迭代器转换为列表并打印
print(list(re.finditer('\d{3}-\d{7}',sr)))
#循环迭代器,将match对象通过group()函数打印匹配到内容
for i in re.finditer('\d{3}-\d{7}',sr):
if i is not None:
print(i.group())
else:
print('未匹配到对象')
#结果为迭代器
#每个list元素为match对象
[]
#打印match对象的内容
025-2322222
match()尝试从字符串的起始部分对模式进行匹配。如果匹配成功,返回一个匹配对象;如果匹配失败,返回 None; 匹配对象的 group()方法用于显示成功的匹配。
sr6 = 'a2bsbccs233scacss'
#表达式‘a{1,3}’从起始位置可以匹配成功
print(re.match('a{1,3}',sr6))
#表达式‘2b.*’从起始位置不能匹配成功
print(re.match('2b.*',sr6))
打印结果: 第一个可以匹配,第二个为None
None
通过group()方法获取匹配到的内容
print(re.match('a{1,3}',sr6).group())
search()方法会在任意位置搜索正则表达式第一次出现的匹配情况(即使可以匹配到多个,也只会获取第一次匹配到的数据)。如果搜索到成功的匹配,会返回一个匹配对象;否则,返回 None。
比如上面的例子
sr6 = 'a2bsbccs233scacss'
print(re.search('233.*',sr6).group())
#打印结果
233scacss
虽然从字符串一开始匹配不到,但是通过搜索在中间位置可以找到匹配的对象,然后通过group()方法获取匹配到的内容。
在正则表达式中加入括号(),进行分组,获取分组内的内容。
比如下面表达式'233(.*)c(.*)',添加了两个分组,通过group(1)和group(2)获取相应内容
print(re.search('233(.*)c(.*)',sr6).group(1))
print(re.search('233(.*)c(.*)',sr6).group(2))
#打印结果
sca
ss
split()函数在正则表达式匹配到内容后,将其他未匹配的内容分割为列表,可支持最大分割次数,类似与字符串str.split()方法。
sr7 = '1234a2344b555556d556677'
#将匹配到字母以为的其他内容分割为一个列表
print(re.split('[a-z]',sr7))
#打印结果
['1234', '2344', '555556', '556677']
参数添加maxsplit次数后
print(re.split('[a-z]',sr7,maxsplit=2))
#打印结果
['1234', '2344', '555556d556677']
----感谢读者的阅读和学习,谢谢大家。
共勉: 东汉·班固《汉书·枚乘传》:“泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。”
-----指水滴不断地滴,可以滴穿石头;
-----比喻坚持不懈,集细微的力量也能成就难能的功劳。