Python正则表达式re.compile()与re.findall()实战解析
本文深入解析Python中re.compile()与re.findall()的核心用法,结合网页爬虫实例演示如何高效提取特定HTML标签内容。详细讲解正则表达式中的贪婪与非贪婪匹配、分组捕获机制以及re.S标志对换行符处理的影响,帮助开发者掌握精准数据抓取技巧。
前言
在网页爬虫开发中,提取特定信息时经常需要结合使用re.compile()与re.findall()两个函数。本文旨在通过具体案例,演示如何从网页源码中精准截取并打印出包含特定类名的表格数据。
网页中的代码:
<span class='tab-details'>某某城市土地规划表</span>
提取的方法:
def parse_response(html):
pattern = re.compile('class=\'tab-details\'>(.*?)</span>',re.S)
items = re.findall(pattern,html)
print(items)
return items
结果:
['某某城市土地规划表']
本节重点解析pattern属性、re.compile()编译机制以及re.findall()提取逻辑的定义与具体用法。
1.pattern:在HTML表单验证中,pattern属性用于定义输入字段需匹配的正则表达式规则。
2.re.compile():该函数用于将正则表达式字符串编译为pattern对象,以便在多次执行时提高性能,同时也支持对已有pattern进行重新编译或修改。
示例场景:在字符串中全局搜索单词"man",并将其替换为"person"。随后通过compile()方法调整正则表达式,使其能同时匹配"man"和"woman",并将它们统一替换为"person"。
<script type="text/javascript">
var str="Every man in the world! Every woman on earth!";
patt=/man/g;
str2=str.replace(patt,"person");
//用person取代man
document.write(str2+"<br />");
patt=/(wo)?man/g;
patt.compile(patt);
str2=str.replace(patt,"person");
//用person取代man或者woman
document.write(str2);
</script>
输出观察:第一行中的"man"被替换为"person",原"woman"变为"woperson";第二行中的"man"和"woman"均被替换为"person",最终结果中仅包含"person",无其他杂乱字符串。
Every person in the world! Every woperson on earth! Every person in the world! Every person on earth!
3.re.findall():此函数较为复杂,核心在于理解非贪婪匹配模式(.*?)的应用。
re.findall()函数用于在指定字符串中查找所有与给定pattern匹配的子串,并以列表形式返回结果。
以下是findall()函数的两种常见调用形式(前文示例采用的是第二种形式):
import re
kk = re.compile(r'\d+')
kk.findall('one1two2three3four4')
#[1,2,3,4]
#注意此处findall()的用法,可传两个参数;
kk = re.compile(r'\d+')
re.findall(kk,"one123")
#[1,2,3]
以下是常用的正则表达式语法总结:
import re
str = 'aabbabaabbaa'
# 一个"."就是匹配除 \n (换行符)以外的任意一个字符
print(re.findall(r'a.b',str))#['aab', 'aab']
# *前面的字符出现0次或以上
print(re.findall(r'a*b',str))#['aab', 'b', 'ab', 'aab', 'b']
# 贪婪,匹配从.*前面为开始到后面为结束的所有内容
print(re.findall(r'a.*b',str))#['aabbabaabb']
# 非贪婪,遇到开始和结束就进行截取,因此截取多次符合的结果,中间没有字符也会被截取
print(re.findall(r'a.*?b',str))#['aab', 'ab', 'aab']
# 非贪婪,与上面一样,只是与上面的相比多了一个括号,只保留括号的内容
print(re.findall(r'a(.*?)b',str))#['a', '', 'a']
str = '''aabbab
aabbaa
bb''' #后面多加了2个b
# 没有把最后一个换行的aab算进来
print(re.findall(r'a.*?b',str))#['aab', 'ab', 'aab']
# re.S不会对\n进行中断
print(re.findall(r'a.*?b',str,re.S))#['aab', 'ab', 'aab', 'aa\n b']
注意区分'.*?'与'(.*?)':前者匹配前后界限之间的所有内容(包括界限),后者仅截取括号内的内容,不包含前后界限。在设定前后边界时,应选择特征明显的字符,以避免截取出非预期的内容。
re.findall中参数re.S的意义:
1.测试字符串变为(末尾额外增加了2个b字符)
str = '''aabbab
aabbaa
bb'''
2.当参数中不包含re.S时,最后一个换行符后的"aab"未被纳入匹配结果。
print(re.findall(r'a.*?b',str))
#['aab', 'ab', 'aab']
3.当参数包含re.S时,正则表达式不会因\n换行符而中断匹配。
print(re.findall(r'a.*?b',str,re.S))
#['aab', 'ab', 'aab', 'aa\n b']
在前述爬虫代码中使用了re.S参数,这是因为网页内容通常按块状结构爬取,各部分之间可能存在换行符(\n),该参数确保跨行内容也能被正确匹配。
def parse_response(html):
pattern = re.compile('class=\'tab-details\'>(.*?)</span>',re.S)
items = re.findall(pattern,html)
print(items)
return items
参考:
1.HTML input pattern 属性
2.Pattern用法(正则表达式)
3.JavaScript compile() 方法
4.Python 正则表达re模块之findall()详解
总结
至此,关于Python正则表达式re.compile()和re.findall()的讲解结束。如需了解更多相关Python re模块内容,请查阅本站往期文章或继续浏览后续教程,感谢支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













