使用正则表达式步骤:
s = r'ab\ncde' # r 防止转义
print(s) # abcde
1.导入re模块
import re
定义字符串
base_str = 'he6ll2ow7or9ld'
base_str1 = '67he6ll2ow7or9ld'
2.定义匹配规则(需要使用compile()方法)
pattern = re.compile(r'\d+')
pattern2 = re.compile(r'\d')
3.开始匹配
3.1 match(‘待匹配的字符串’) 只匹配成功一次
match()默认从头开始匹配,如果字符串中的第一个字符不符合制定的规则,直接返回None
不会继续向下进行匹配
如果使用字符串中的第一个字符符合匹配规则,返回匹配成功的内容(match对象),不会继续向下匹配
result1 = pattern.match(base_str)
print(result1) # None(匹配不成功)
# base_str = '6he6ll2ow7or9ld'
# pattern = re.compile(r'\d+')
# result1 = pattern.match(base_str)
# print(result1) # <re.Match object; span=(0, 1), match='6'>
match(‘待匹配的字符串’,[,start,end]) 从指定返回中进行匹配
result2 = pattern2.match(base_str1,7,10)
print(result2) # <re.Match object; span=(7, 8), match='2'>
3.2 group() 分组
group_str = '4h3e2lloworld'
pattern3 = re.compile(r'\dh\de\dl')
res = pattern3.match(group_str)
print(res) # <re.Match object; span=(0, 6), match='4h3e2l'>
print(res.group()) # 4h3e2l
pattern4 = re.compile(r'(\d)h(\d)e(\d)l') # 加()分组
res = pattern4.match(group_str)
print(res.group()) # 4h3e2l
print(res.group(0)) # 4h3e2l
print(res.group(1)) # 4
print(res.group(2)) # 3
print(res.group(3)) # 2
分组的反向引用(拓展)
注意:
反向引用不代表分组,只是前面分组的值的引用
html_str = '<html><h1>helloPython<h2></html>'
pattern = re.compile(r'<html><h1>(.*)<h2></html>')
res = pattern.match(html_str)
print(res) # <re.Match object; span=(0, 32), match='<html><h1>helloPython<h2></html>'>
print(res.group(1)) # helloPython
pattern = re.compile(r'<(html)><(h1)>(.*)<h2></html>')
res1 = pattern.match(html_str)
print(res1.group(1)) # html
print(res1.group(2)) # h1
print(res1.group(3)) # helloPython
html_str1 = '<html><h1>helloPython</h1></html>'
pattern = re.compile(r'<(html)><(h1)>(.*)</\2></\1>')
res2 = pattern.match(html_str1)
print(res2.group(1)) # html
print(res2.group(2)) # h1
print(res2.group(3)) # helloPython
**3.3 search(待匹配字符串[,start,end]),**从头开始匹配
search()方法是全局匹配,如果整个字符串中都没有符合匹配规则的,才会返回None
如果匹配成功,直接返回匹配成功的字符串,不会继续向下匹配,只匹配成功一次
search_str = 'h3e2l5l7oworld'
pattern = re.compile(r'\d')
res = pattern.search(search_str)
print(res) # <re.Match object; span=(1, 2), match='3'>
pattern = re.compile(r'\d+')
res = pattern.search(search_str)
print(res) # <re.Match object; span=(1, 2), match='3'>
3.4 findall()方法 和match\search都不一样
findall() 全局匹配 会将匹配字符串中所有符合规则的字串全部返回
返回的是一个列表,列表中的每一个元素都是匹配成功的子串
返回的内容不是match对象
如果整个字符串中都没有符合匹配规则的内容,返回的是空列表,而不是None
findall_str = 'h3e2ll5o6p8yt9hon'
pattern = re.compile(r'\d')
res = pattern.findall(findall_str)
print(res) # ['3', '2', '5', '6', '8', '9']
pattern1 = re.compile(r'v')
res1 = pattern1.findall(findall_str)
print(res1) # []
3.5 finditer()方法 和 findall()方法很类似
- 都是全局匹配 findall返回列表
- finditer 返回的是可迭代对象
finditer_str = 'h3e1l4lo5wo6rl8d'
pattern = re.compile(r'\d')
res = pattern.finditer(finditer_str)
print(res) # <callable_iterator object at 0x000001940972E978>
for i in res:
# print(i) # match对象
# <callable_iterator object at 0x000002600E2E3D30>
# <re.Match object; span=(1, 2), match='3'>
# <re.Match object; span=(3, 4), match='1'>
# <re.Match object; span=(5, 6), match='4'>
# <re.Match object; span=(8, 9), match='5'>
# <re.Match object; span=(11, 12), match='6'>
# <re.Match object; span=(14, 15), match='8'>
print(i.group())
# <callable_iterator object at 0x0000016B49E992E8>
# 3
# 1
# 4
# 5
# 6
# 8
3.6 贪婪模式 和 非贪婪模式
html = '<div>hello</div><div>world</div><div>python</div>'
贪婪模式:尽可能多的获取 .*
pattern = re.compile(r'<div>.*</div>')
res = pattern.findall(html)
print(res) # ['<div>hello</div><div>world</div><div>python</div>']
非贪婪模式:尽可能少的获取 .*?
pattern = re.compile(r'<div>.*?</div>')
res = pattern.findall(html)
print(res) # ['<div>hello</div>', '<div>world</div>', '<div>python</div>']
3.7 匹配中文
中文的编码范围:[\u4e00-\u9fa5]
cn_str = 'hello 你好 world 世界'
pattern = re.compile(r'[\u4e00-\u9fa5]+')
res = pattern.findall(cn_str)
print(res) # ['你好', '世界']
爬虫中万能的正则表达式匹配规则:
.*?(配合边界值),再配上re.S(能够匹配到换行) ---> 无敌表达式
re.compile(r'<边界>(.*?)<边界>',re.S)