在解析网页时,有一个需求是将网页内容按<h2>.*<h2>
划分开,很容易想到,re.split()
可以实现这一功能。
话不多说,我们进入正题:
import re
test_data = """
今天天气真不错
<h2>是的</h2>
真不错啊
真不错
"""
res = re.findall(r'<h2>.*</h2>', test_data, re.S)
print(res)
输出
['\n今天天气真不错\n', '\n真不错啊\n真不错\n']
很简单,实现了我们的需求。那么,我们再改一下test_data
试试:
import re
test_data = """
今天天气真不错
<h2>是的
</h2>
真不错啊
真不错
"""
res = re.split(r'<h2>.*</h2>', test_data, re.S)
print(res)
输出:
['\n今天天气真不错\n<h2>是的\n</h2>\n真不错啊\n真不错\n']
仔细看,我们仅仅是添加了个换行,就导致我们写的正则表达式不起作用
我们把split
换成findall
试试:
import re
test_data = """
今天天气真不错
<h2>是的
</h2>
真不错啊
真不错
"""
res = re.findall(r'<h2>.*</h2>', test_data, re.S)
print(res)
输出:
['<h2>是的\n</h2>']
看起来findall
是没问题的,我们看下re.S
的作用
re.S
在re.findall
中是起了作用的,但在re.split
就失效了,此时,我们已经明确了原因:
re.S
未起作用
于是,我看了下re.split
的函数说明:
我们是这样写的:res = re.split(r'<h2>.*</h2>', test_data, re.S)
发现问题了吗?我们将maxsplit
参数设置为re.S
了
正确的写法应该是这样:
import re
test_data = """
今天天气真不错
<h2>是的
</h2>
真不错啊
真不错
"""
res = re.split(r'<h2>.*</h2>', test_data, flags=re.S)
print(res)
输出:
['\n今天天气真不错\n', '\n真不错啊\n真不错\n']
这时,有些同学可能会问:为什么findall
可以正确提取呢?
我们来看下re.findall
的函数说明:
可以看出,re.findall
的第三个参数就是flags
,所以,将re.S
写在re.findall
函数的第三个参数的位置是没有任何问题的。
那么,有没有更省心的办法呢?
当然有!!!!
我们使用re.compile
函数:
import re
test_data = """
今天天气真不错
<h2>是的
</h2>
真不错啊
真不错
"""
pattern = re.compile(r'<h2>.*</h2>', re.S)
res = pattern.split(test_data)
print(res)
输出:
['\n今天天气真不错\n', '\n真不错啊\n真不错\n']
同样实现了我们的需求。
在日常开发中,在用到正则的地方,我们应养成使用re.compile
编译正则表达式的好习惯,这样写不但可以避免犯这篇文章同样的错误,还能提升效率。