正则表达式是爬虫,Web开发,数据处理等各类涉及到文本处理的一把锋利的瑞士军刀,是每个程序员必须掌握的一门技能。
# 1. 正则表达式的7个境界
'''要确定文本中是否包含数字123456,我们可以用in运算符,也可以使用index函数'''
text = '身高:178,体重:168,学号:123456,密码:9527'
target = '123456'
if target in text:
print('find it')
print(text.index(target))
# level1 - 固定的字符串
'''
要求:确定字符串中是否有123456
findall()方法的第1个参数是模式,第2个参数是要查找的字符串
模式中会有一些特殊字符,所以用r表示这是一个raw字符串,让Python不要去转义里面的特殊字符
level1就是一个固定的字符串匹配,可以用传统的字符串匹配解决
'''
import re
text = '身高:178,体重:168,学号:123456,密码:9527'
print(re.findall(r'123456',text))
# level2 - 某一类字符
'''
要求:找出所有的单个的数字
这个表达式\d表示所有的数字,所以1,7,8,1,6,8等都可以匹配到。这是很简单的模式,只匹配1个单独的数字
'''
text = '麦叔身高:178,体重:168,学号:123456,密码:9527'
print(re.findall(r'\d',text))
# level3 - 重复某一类字符
'''
要求:找所有的数字,比如178,168,123456,9527等。
这个模式\d+在\d的后面增加了+号,表示数字可以出现1到多次,所以178等都符合它的要求
'''
text = '麦叔身高:178,体重:168,学号:123456,密码:9527'
print(re.findall(r'\d+',text))
# leve4 - 组合level2
'''
要求:找出座机号码
\d{4}-\d{8}这是一个组合的模式,表示前面4个数字,中间一个横杠,后面8个数字
'''
text = '麦叔电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
print(re.findall(r'\d{4}-\d{8}',text))
# leve5 - 多种情况
'''
要求:找出手机号码或者座机号码
比上面有复杂了点,因为使用竖线(|)来表示”或“的关系,就是手机号码和电话号码都可以
'''
text = '麦叔电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
print(re.findall(r'\d{4}-\d{8}|1\d{10}',text))
# level6 - 限定位置
'''
要求:在句子开头的手机号码,或座机
在表达式的最开始使用了^符号,表示一定要在句子的开头才行。这时候只有18812345678能匹配上
'''
text = '18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
print(re.findall(r'^\d{4}-\d{8}|^1\d{10}',text))
# level7 - 内部约束
'''
要求:找出形如barbar, dardar的前后三个字母重复的字符串
\w{3}表示3个字符,放在小括号中(\w{3})就成为一个分组,而后面的(\1)表示它里面的内容和第1个括号里的内容必须相同,其中的1就表示第1个括号,也就是说3个字符要重复出现两次
'''
text = 'barbar carcar harhel'
print(re.findall(r'(\w{3})(\1)',text))
# 2. 写正则表达式的步骤
'''
确定模式包含几个子模式
各个部分的字符分类是什么
各个子模式如何重复
是否有外部位置限制
是否有内部制约关系
'''
text = '随机数字:01234567891,座机1:0571-52152166,座机2:0571-52152188-1234'
print(re.findall(r'\d{3,4}-\d{7,8}-\d{3,4}|\d{3,4}-\d{7,8}', text))
# 3. Python正则模块re的用法
t = \
(
'''
<1> 查找
re.search():查找符合模式的字符,只返回第一个,返回Match对象
re.match():和search一样,但要求必须从字符串开头匹配
re.findall():返回所有匹配的字符串列表
re.finditer():返回一个迭代器,其中包含所有的匹配,也就是Match对象
<2> 替换
re.sub():替换匹配的字符串,返回替换完成的文本
re.subn():替换匹配的字符串,返回替换完成的文本和替换的次数
<3> 分割
re.split():用匹配表达式的字符串做分隔符分割原字符串
re.compile():把正则表达式编译成一个对象,方便后面使用
'''
)
# print(t)
import re
text = "aBc,Abc,ABC"
m = re.search(r'abc',text,flags=re.I)
print(m.group())
text = '18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
m = re.search(r'(\d{4})-(\d{8})',text)
print(m.group(),m.group(1),m.group(2))
# match
import re
text = "xaBc,Abc,ABC"
m = re.match(r'abc',text,flags=re.I)
print(m)
# findall
import re
text = "xaBc,abc,ABC"
m = re.findall(r'abc',text,flags=re.I)
print(m)
# findall
import re
text = "ABC,abc,xaBc"
m = re.findall(r'^abc',text,flags=re.I)
print(m)
import re
text = "abbb ,accc "
m = re.findall(r'ac*',text,flags=re.I)
print(m)
# findall
text = '18812345678,他还有一个电话号码是18887654321,他爱好的数字是0571-52152188,他的座机是:0571-52152166'
m = re.findall(r'\d{4}-\d{8}',text)
print(m)
# finditer
text = '18812345678,他还有一个电话号码是18887654321,他爱好的数字是0571-52152188,他的座机是:0571-52152166'
it = re.finditer(r'\d{4}-\d{8}',text)
for m in it:
print(m.group())
# sub
import re
text = "aBc,Abc,ABC,fafafafa"
m = re.sub(r'abc','***',text,flags=re.I)
print(m)
# subn
import re
text = "aBc,Abc,ABC,fafafafa"
m = re.subn(r'abc','***',text,flags=re.I)
print(m)
# match
import re
text = "xaBc,Abc,ABC"
list = []
for i in text.split(','):
m = re.match(r'abc',i,flags=re.I)
if m != None:
list.append(m.group())
print(list)
text = "xaBc,Abc,ABC"
m = re.findall(r'abc',text,flags=re.I)
print(m)
text = "Abc,ABC"
m = re.match(r'abc',text,flags=re.I)
print(m.group())