作者:永不落的梦想
作者主页:传送
座右铭:过去属于死神,未来属于自己
本文专栏:Python篇
今日鸡汤:人最大的对手,就是自己的懒惰
目录
一、概述
正则表达式是一个特殊的字符序列,方便检查一个字符串是否与某种模式匹配;
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式,re 模块使 Python 语言拥有全部的正则表达式功能。
二、正则表达式模式
模式 | 描述 |
字符类 | |
a,b,c,1,2,3 | 字符常量,直接匹配常量 |
\d | 匹配一个数字 |
\D | 匹配一个非数字 |
\s | 匹配一个空格 |
\S | 匹配一个非空格 |
\w | 匹配一个字母、数字或下划线 |
\W | 匹配一个非字母、数字、下划线 |
[abcd] | 匹配abcd中任意一个字符 |
[a-d] | 匹配a-d中任意一个字符 |
[^a-d] | 匹配除a-d外的任意一个字符 |
[0-5] | 匹配0-5中任意一个字符 |
. | 匹配除\n外的任意一个字符 |
量词 | |
* | 0或多个 |
+ | 1或多个 |
? | 0或1个 |
{3} | 3个 |
{2,5} | 2-5个 |
{3,} | 至少3个 |
{,4} | 最多4个 |
组合模式 | |
\d{3}[a-z]{3} | 直接拼接多个子模式,表示3个数字连接3个小写字母 |
\d{3}|[a-z]{3} | 模式并存,表示匹配3个数字或3个小写字母 |
(abc){3} | 分组,表示abc为一组匹配3个即abcabcabc |
(abc)(ha)(\1) | 分组调用,\1表示第一个分组即匹配abchaabc |
位置 | |
^ | 匹配开头 |
$ | 匹配末尾 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束 |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
标记 | |
re.I | 忽略大小写 |
re.M | 多行匹配 |
re.X | 允许空格和注释 |
re.S | .可匹配\n |
特殊字符 | |
\n | 匹配换行符 |
\r | 匹配回车符 |
\t | 匹配tab符 |
import re
# 简单正则模式匹配案例
s = '123abc,hello word! HHHaa'
# 匹配模式:r'abc' 匹配结果:匹配成功
# 匹配模式:r'\d+abc' 匹配结果:匹配成功
# 匹配模式:r'\d{3}[a-z]{3}' 匹配结果:匹配成功
# 匹配模式:r'\d+[a-z]' 匹配结果:匹配成功
# 匹配模式:r'^[a-zA-Z]+' 匹配结果:匹配失败
# 匹配模式:r'Haa/b' 匹配结果:匹配成功
# 匹配模式:r'^[^a-z]' 匹配结果:匹配成功
# 匹配模式:r'\d{1,}' 匹配结果:匹配成功
# 匹配模式:r'a.c' 匹配结果:匹配成功
# 匹配模式:r'[a-z]{2,}$' 匹配结果:匹配成功
注意:
标点符号只有被转义时才匹配自身,否则它们表示特殊的含义;
反斜杠本身需要使用反斜杠转义;
由于正则表达式通常都包含反斜杠,所以最好使用原始字符串来表示它们,模式元素(如 r'\t',等价于 \\t) 匹配相应的特殊字符;
三、re模块常用方法
查找 | |
re.search() | 只返回一个匹配结果的对象 |
re.match() | 从头匹配且只返回一个匹配结果的对象 |
re.findall() | 返回元素为所有匹配结果的列表 |
re.finditer() | 返回Match迭代器的对象 |
替换 | |
re.sub() | 返回所有匹配结果被替换后的字符串 |
re.subn() | 返回元素为替换后的字符串和替换次数的元组 |
分割 | |
re.split() | 返回元素为以匹配模式作为分隔后的字符串的列表 |
# re模块常用方法使用案例
import re
a = '22abc,Abc,ABC,aj145a,kl8899'
# re.search(),只返回一个匹配结果的对象
m1 = re.search(r'\d{2}', a, flags=re.I)
print('\nre.search()的结果:')
print(m1)
# re.match(),从头匹配且只返回一个匹配结果的对象
m2 = re.match(r'j\d{2}', a)
m3 = re.match(r'\d{2}', a)
print('\nre.match()的结果:')
print(m2)
print(m3)
# re.findall(),返回元素为所有匹配结果的列表
m4 = re.findall(r'\d{2}', a)
print('\nre.findall()的结果:')
print(m4)
# re.finditer(),返回Match迭代器的对象
m5 = re.finditer(r'\d{2}', a)
print('\nre.finditer()的结果:')
for i in m5:
print(i)
# re.sub(),返回所有匹配结果被替换后的字符串
m6 = re.sub(r'\d{2}', '--', a)
print('\nre.sub()的结果:')
print(m6)
# re.subn(),返回元素为替换后的字符串和替换次数的元组
m7 = re.subn(r'\d{2}', '--', a)
print('\nre.subn()的结果:')
print(m7)
# re.split(),返回元素为以匹配模式作为分隔后的字符串的列表
b = 'ahs, ajka / koi12 ? jk'
m8 = re.split(r'\s*[,/?]\s*', b)
print('\nre.split()的结果:')
print(m8)
# 输出
re.search()的结果:
<re.Match object; span=(0, 2), match='22'>
re.match()的结果:
None
<re.Match object; span=(0, 2), match='22'>
re.findall()的结果:
['22', '14', '88', '99']
re.finditer()的结果:
<re.Match object; span=(0, 2), match='22'>
<re.Match object; span=(16, 18), match='14'>
<re.Match object; span=(23, 25), match='88'>
<re.Match object; span=(25, 27), match='99'>
re.sub()的结果:
--abc,Abc,ABC,aj--5a,kl----
re.subn()的结果:
('--abc,Abc,ABC,aj--5a,kl----', 4)
re.split()的结果:
['ahs', 'ajka', 'koi12', 'jk']
四、正则匹配案例
匹配Email地址的正则表达式 |
\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)* |
匹配网址URL的正则表达式 |
[a-zA-Z]+://[^\s]* |
匹配腾讯QQ号的正则表达式 |
[1-9]\d{4,} |
匹配身份证号的正则表达式 |
\d{15}|\d{18} |
匹配IPv4地址的正则表达式 |
(\d{1,3}).(\1).(\1).(\1) |