一.写正则表达式的步骤
以包含分机号码的座机电话号码为例,比如0571-88776655-9527,演示下面的步骤:
1. 确定模式包含几个子模式
它包含3个子模式:0571-88776655-9527。这3个子模式用固定字符连接。
2. 各个部分的字符分提什么
这3个子模式都是数字类型,可以用\d。现在可以写出模式为:1d-\d-\d
3. 各个部分如何重复
第1个子摸式重复3到4次,因为有010和021等直辖市
第2个子模式重复7到8次,有的地区只有7位电话号码
第3个子模式重复3-4次
加上次数限制后,模式成为:1d3,4]\d{7,8]-\d3,4),但有的座机没有分机号,所以我们用或运算符让它支持两者:\d{3,4}-\d{7,8}-\d3,4}1d{3.43-\d{7,8}
4. 是否有外部位置限制没有
5· 是否有内部制约关系
没有
经过一通分析,最后的正则就写成了,测试一下:
te×t='随机数字:01234567891,座机10571-52152166,座机2:0571-52152188-12342
print(re.finda11(rd{3,4}-\d{7,8}-\d{3,4}ld[3,4)-\d{7,8}',text))
import re
import logging.config
logging.config.fileConfig("log/logging.conf")
logger = logging.getLogger("applog")
text = "13811100011电话,我的身高是:172, 体重:170, 学号:123456, 密码:98788, 喜欢的数字:123456789898989, 座机:0527-01234567-123或021-1234567"
# 1. 查找固定的字符串
ret = re.findall(r"123456", text)
logger.debug(ret)
# 2. 查找某一类字符
ret2 = re.findall(r"\d", text)
# ret3 = re.findall(r"[高重号]", text) # 表示找到[]里的任何一个字符,或的关系
logger.debug(ret2)
# logger.debug(ret3)
# 3. 重复某一类字符,通配符和{}表示这个字符具体要重复几次
ret4 = re.findall(r"\d+", text) # 数字字符重复多次
ret5 = re.findall(r"\d{3}", text) # 数字字符重复3次
ret6 = re.findall(r"\d{1,4}", text) # 数字字符重复1,2,3,4次都可以
logger.debug(ret4)
logger.debug(ret5)
logger.debug(ret6)
# 4. 某一类字符的组合
ret7 = re.findall(r"\d{3,4}-\d{7,8}-\d{3,4}", text) # 匹配座机号
logger.debug(ret7)
# 5. 多种情况,| 表示或
ret8 = re.findall(r"\d{3,4}-\d{7,8}-\d{3,4}|1\d{10}", text) # 匹配手机号或者座机号
logger.debug(ret8)
# 6. 限定位置
ret8 = re.findall(r"\d{3,4}-\d{7,8}$|\d{3,4}-\d{7,8}-\d{3,4}$|^1\d{10}", text)
logger.debug(ret8)
# 7. 内部约束
text2 = "car87car, dar2dar, hei66heq"
ret9 = re.findall(r"(\w{3})(\d{1,2})(\1)", text2) # ()表示分组,(\1)表示和前面第一组相同
logger.debug(ret9)
2022/05/20 16:46:53|DEBUG |1-1.py | 12|MainThread|['123456', '123456', '123456', '123456']
2022/05/20 16:46:53|DEBUG |1-1.py | 18|MainThread|['1', '3', '8', '1', '1', '1', '0', '0', '0', '1', '1', '1', '7', '2', '1', '7', '0', '1', '2', '3', '4', '5', '6', '9', '8', '7', '8', '8', '1', '2', '3', '4'
, '5', '6', '7', '8', '9', '8', '9', '8', '9', '8', '9', '0', '5', '2', '7', '0', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '0', '2', '1', '1', '2', '3', '4', '5', '6', '7']
2022/05/20 16:46:53|DEBUG |1-1.py | 25|MainThread|['13811100011', '172', '170', '123456', '98788', '123456789898989', '0527', '01234567', '123', '021', '1234567']
2022/05/20 16:46:53|DEBUG |1-1.py | 26|MainThread|['138', '111', '000', '172', '170', '123', '456', '987', '123', '456', '789', '898', '989', '052', '012', '345', '123', '021', '123', '456']
2022/05/20 16:46:53|DEBUG |1-1.py | 27|MainThread|['1381', '1100', '011', '172', '170', '1234', '56', '9878', '8', '1234', '5678', '9898', '989', '0527', '0123', '4567', '123', '021', '1234', '567']
2022/05/20 16:46:53|DEBUG |1-1.py | 31|MainThread|['0527-01234567-123']
2022/05/20 16:46:53|DEBUG |1-1.py | 35|MainThread|['13811100011', '12345678989', '0527-01234567-123']
2022/05/20 16:46:53|DEBUG |1-1.py | 39|MainThread|['13811100011', '021-1234567']
2022/05/20 16:46:53|DEBUG |1-1.py | 44|MainThread|[('car', '87', 'car'), ('dar', '2', 'dar')]
?
?
?
?
?
二.re模块
①查找
re.search-只返回1个,返回的是Match迭代器,Match.groups(),Match.group()获取匹配项
re.match-从头开始匹配,只返回1个,返回的是Match迭代器,Match.groups()获取匹配项
re.findall-返回字符串
re.finditer-返回Match迭代器
②替换
re.sub
re.subn
③分割
re.split
④创建一个正则表达式对象
re.compile()
import re
import logging.config
logging.config.fileConfig("log/logging.conf")
logger = logging.getLogger("applog")
text = "aBc, abc, asdqwe, ABC"
# re.findall()
ret3 = re.findall(r"abc", text, flags=re.I)
logger.debug(ret3)
# re.search(),只查找第一个匹配想,返回Match对象(匹配不到返回None),通过Match.groups(),Match.group()获取匹配项
m = re.search(r"abc", text, flags=re.I) # re.I表示忽略大小写
m2 = re.search(r"(\w{3}), (\w{3})", text)
ret = m.group() # 返回匹配项
ret2 = m2.groups() # 返回一个元祖。用groups()时,正则表达式里必须要先分组,否则返回空元祖
logger.debug(m)
logger.debug(m2)
logger.debug(ret)
logger.debug(ret2)
# re.match(),必须从第一个字符开始匹配,其他和search()一样
m3 = re.match(r"aBc", text)
logger.debug(m3)
ret3 = m3.group() # 返回匹配项
logger.debug(ret3)
m4 = re.match(r"(\w{3}), (\w{3})", text)
logger.debug(m4)
ret4 = m4.groups() # 返回一个元祖。用groups()时,正则表达式里必须要先分组,否则返回空元祖
logger.debug(ret4)
# re.sub() 用指定的字符串替换匹配的字符串,返回替换后的字符串
ret5 = re.sub(r"abc", "***", text, flags=re.I)
logger.debug(ret5)
# re.subn() 返回值里比sub()多返回了替换了几个位置,其他都一样
ret6 = re.subn(r"abc", "***", text, flags=re.I)
logger.debug(ret6)
# re.split() 返回分割后的字符串列表
text2 = "asd,zxc . iupo? oi /fgd dfg asdas"
ret7 = re.split(r"\s*[,.?/]\s*|\s+", text2)
logger.debug(ret7)
# re.compile() 创建一个正则表达式对象
re_cmp = re.compile("abc", flags=re.I)
ret8 = re_cmp.findall(text)
logger.debug(ret8)
# 运行结果
2022/05/20 18:14:27|DEBUG |1-2-re.py | 11|MainThread|['aBc', 'abc', 'ABC']
2022/05/20 18:14:27|DEBUG |1-2-re.py | 18|MainThread|<re.Match object; span=(0, 3), match='aBc'>
2022/05/20 18:14:27|DEBUG |1-2-re.py | 19|MainThread|<re.Match object; span=(0, 8), match='aBc, abc'>
2022/05/20 18:14:27|DEBUG |1-2-re.py | 20|MainThread|aBc
2022/05/20 18:14:27|DEBUG |1-2-re.py | 21|MainThread|('aBc', 'abc')
2022/05/20 18:14:27|DEBUG |1-2-re.py | 25|MainThread|<re.Match object; span=(0, 3), match='aBc'>
2022/05/20 18:14:27|DEBUG |1-2-re.py | 27|MainThread|aBc
2022/05/20 18:14:27|DEBUG |1-2-re.py | 30|MainThread|<re.Match object; span=(0, 8), match='aBc, abc'>
2022/05/20 18:14:27|DEBUG |1-2-re.py | 32|MainThread|('aBc', 'abc')
2022/05/20 18:14:27|DEBUG |1-2-re.py | 36|MainThread|***, ***, asdqwe, ***
2022/05/20 18:14:27|DEBUG |1-2-re.py | 40|MainThread|('***, ***, asdqwe, ***', 3)
2022/05/20 18:14:27|DEBUG |1-2-re.py | 45|MainThread|['asd', 'zxc', 'iupo', 'oi', 'fgd', 'dfg', 'asdas']
2022/05/20 18:14:27|DEBUG |1-2-re.py | 50|MainThread|['aBc', 'abc', 'ABC']
|