正则表达式
正则表达式的常见使用场景
1:判断某一个字符串是否符合规则 #注册页-判断手机号-身份证
2:将符合规则的内容从一个庞大的字符串体系中提取出来
#爬虫日志分析
什么是正则表达式?
1:是一种规则
一:正则表达式步骤
1.用 import re 导入正则表达式模块。
2.用 re.compile()函数创建一个 regex 对象(记得使用原始字符串)。
3.向 regex 对象的 search()方法传入想查找的字符串。它返回一个 match 对象
4.调用 match 对象的 group()方法,返回实际匹配文本的字符串。
补充:regex 对象的 search()方法查找传入的字符串, 寻找该正则表达式的所有匹配。如果字符串中没有找到该正则表达式模式,search()方法将返回 none。如果找到了该模式,search()方法将返回一个 match 对象。
二:用正则表达式匹配更多模式
2.1:利用括号分组
phonenumregex = re.compile('(d{3})-(d{3})-(d{4})')
mo = phonenumregex.search('my number is 444-333-3333')
print(mo.group(1)) #444
print(mo.group(0)) #444-333-3333
print(mo.group()) #向group传0或者不传值匹配的都是字符串
print(mo.groups())#('444', '333', '3333')
2.2:用管道匹配多个分组
heroregex = re.compile(r'batman|雷文轩')
mo = heroregex.search('雷文轩 and batman')
print(mo.group())#雷文轩 匹配一个就退出
heroregex = re.compile(r'雷(文轩|一鸣|英)')
mo = heroregex.search(' 雷文轩, 雷文轩and 雷英')
print(mo.group()) #匹配其中一个
2.3:用问好实现可选匹配
正则表达式中的(文)?部分表明, 模式 wo 是可选的分组。该正则表达式匹配的文本中, 文将出现零次或一次。
batregex = re.compile(r'雷(文)?轩')
mo = batregex.search('my name is 雷轩')
print(mo.group()) #雷轩
2.4:用星号匹配零次或多次
(称为星号)意味着“匹配零次或多次”,即星号之前的分组或者一个元字符,可以在文本中出现任意次。它可以完全不存在,或一次又一次地重复。
batrgex = re.compile(r'bat(wo)*man')
mo = batrgex.search(' the adventures of batman')
print(mo.group()) #batman
mo1 = batrgex.search(' the adventures of batwoman')
print(mo1.group()) #batwoman
mo2 = batrgex.search(' the adventures of batwowowoman')
print(mo2.group()) #batwowowoman
2.5:用加号匹配一次或多次
正则表达式 bat(wo)+man 不会匹配字符串'the adventures of batman',因为加号要求 wo 至少出现一次。如果需要匹配真正的加号字符, 在加号前面加上倒斜杠实现转义: +。
#batregex = re.compile('bat(wo)+man')
mo = batregex.search('the adventures of batwoman')
print(mo.group()) #batwoman
#******
mo = batregex.search('the adventures of batman')#+ 号代表一次或者多次
print(mo == none) #匹配队里里为空 等于none
2.5:用花括号匹配特定次数
如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括号包围的数字。例如,正则表达式(ha){3}将匹配字符串'hahaha',但不会匹配'haha',因为后者只重复了(ha)分组两次。除了一个数字,还可以指定一个范围,即在花括号中写下一个最小值、一个逗号和一个最大值。例如,正则表达式(ha){3,5}将匹配'hahaha'、 'hahahaha'和'hahahahaha'。
也可以不写花括号中的第一个或第二个数字, 不限定最小值或最大值。例如,(ha){3,}将匹配 3 次或更多次实例, (ha){,5}将匹配 0 到 5 次实例。花括号让正则表达式更简短。这两个正则表达式匹配同样的模式:
hareget = re.compile(r'(ha){3}')#匹配hahaha
mo = hareget.search('hahaha') #不会匹配haha
print(mo.group())#hahaha
2:6贪心和非贪心匹配
greedyharegex = re.compile(r'(ha){3,5}')
mo = greedyharegex.search('hahahaha')
print(mo.group()) #hahahaha 他会匹配更长的值
nongeedyharegex = re.compile(r'(ha){3,5}?')
mo2 = nongeedyharegex.search('hahahahaha')
print(mo2.group())#hahaha 尽量取少的模式
#贪婪匹配:正则会尽量多的帮我们匹配, 默认贪婪,回溯算法
#非贪婪匹配:会尽量少的为我们匹配,
1:
三:findall()方法
phonenumregex = re.compile(r'(d{3})-(d{3})-(d{4})')
mo = phonenumregex.findall('cell: 415-555-9999 work: 212-555-0000')
print(mo) #[('415', '555', '9999'), ('212', '555', '0000')]
#1:返回一个字符串列表,. 如果调用在一个有分组的正则表达式上,
#2:方法 findall()将返回一个字符串的元组的列表(每个分组对应一个字符串),
#3:会优先显示分组中的内容 ,(?:) 取消分组优先
四:字符分类
1. 元字符
匹配内容
. 匹配除换行符以外的任意字符
w 匹配字母或数字或下划线
s 匹配任意的空白符
d 匹配数字
匹配一个换行符
匹配一个制表符
匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结尾
W 匹配非字母或数字或下划线
D 匹配非数字
S 匹配非空白符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
例如:字符分类[0-5]只匹配数字 0 到 5, 这比输入(0|1|2|3|4|5)要短很多。
![字符分类](https://i.imgur.com/P2Udbd6.png)
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
2018/9/10/周一 10:04:49
4.1:插入字符和美元字符
1. 可以在正则表达式的开始处使用插入符号(^),表明匹配必须发生在被查找文本开始处
2. 类似地,可以再正则表达式的末尾加上美元符号($),表示该字符串必须以这个正则表达式的模式结束。可以同时使用^和$,表明整个字符串必须匹配该模式,也就是说,只匹配该字符串的某个子集是不够的。
4.2不区分大小写的匹配
1. rebocp = re.compile(r'leiWenXuan',re.I)
2. #忽略大小写 re.IGNORECASE 或者re.I
3. mo = rebocp.search('Leiwenxuan livs in chain')
4. print(mo.group())
用 sub()方法替换字符串
1. sub_mo = re.compile('Agent w+')
2. mo = sub_mo.sub('leiwenxuan', 'Agent Alice gave the secret documents to Agent Bob.')
3. print(mo) #leiwenxuan gave the secret documents to leiwenxuan.
4. 对象的 sub()方法需要传入两个参数。第一个参数是一个字符串, 用于取代发现的匹配。第二个参数是一个字符串,即正则表达式。
1. agentNameRggex = re.compile(r'Agent (w)w*')
2. mo = agentNameRggex.sub(r'1****', 'Agent Alice told Agent Carol that AgentEve knew Agent Bob was a double agent.')
3. print(mo)
管理复杂的正则表达式
1. phoneRegex = re.compile(r'''
w #可以加注释
''', re.VERBOSE)
2.mo = phoneRegex.findall('erhja')
3.print(mo)