Python正则表达式findall函数详解与实战案例
本文深入解析Python中正则表达式模块re的findall方法。通过具体代码示例,详细讲解如何提取字符串中的数字、单词及特定模式。重点阐述贪婪匹配与非贪婪匹配的区别,以及使用括号进行分组捕获的原理。同时涵盖多行字符串匹配时的re.S标志应用,以及结合sub和split函数进行数据清洗的实战技巧,帮助开发者高效处理文本数据。
Python正则表达式基础与findall概述
正则表达式的基本逻辑通常遵循“知道前后,提取中间”的原则,若需匹配至字符串末尾,则使用$符号作为结束标识。
在Python中,正则表达式匹配主要依赖re模块提供的三个核心方法:re.match、re.search以及re.findall。
使用re.findall进行匹配时,若找到所有匹配项,会将结果以列表形式返回;若未找到任何匹配内容,则返回空列表,而不会抛出错误。
基础数字匹配示例
import re
s1=re.compile('\d+')
# 匹配数字
r1=s1.findall('sahduasu27bhsagd7236vbcsahg923')
print(r1)
s2=re.compile('\d+')
r2=re.findall(s2, 'gashgddsh32hjsagd3jh4hjk234jkhk213')
print (r2)
r3=re.findall('\d+', 'sjdjsk1232kdsjf324string')
print(r3)
# 执行结果
# ['27', '7236', '923']
# ['32', '3', '4', '234', '213']
# ['1232', '324']以下是具体的代码示例及常用操作方式:
字符匹配与量词使用
import re
a = "hfdsakjhabsdgfjhabhjgdjabhjgajbkdkjdhfkaab"
# 1.找出字符串中有多少个ab, 两个字符挨着
r1= re.findall(r"ab", a)
print(r1)
# 继续查找如ab, aab, aaab,aaaab这种,a可以重复,也就是匹配前面的a是1个或多个
# +是代表前面的字符出现1次或多次
r2= re.findall(r"a+b", a)
print(r2)
# *是代表匹配前面的字符出现0次或多次
r3= re.findall(r"a*b", a)
print(r3)
# 我们要匹配a和b之间有一个字符的,比如aab,abb,acb,adb都符合
# .就是匹配除 \n (换行符)以外的任意一个字符
r4= re.findall(r"a.b", a)
print(r4)
# 执行结果:
# ['ab', 'ab', 'ab', 'ab']
# ['ab', 'ab', 'ab', 'aab']
# ['ab', 'ab', 'ab', 'b', 'aab']
# ['ajb', 'aab']理解贪婪匹配与非贪婪匹配是掌握正则表达式的关键。
贪婪与非贪婪匹配机制
import re
# 符号.* 贪婪,匹配从.*前面为开始到后面为结束的所有内容
a = "hfdsakjhabsdgfjhabhjgdjabhjgajbkdkjdhfkaabsdf"
r1= re.findall(r"a.*b", a)
print(r1)
# 符号.*? 非贪婪,遇到开始和结束就进行截取,因此截取多次符合的结果,中间没有字符也会被截取
r2= re.findall(r"a.*?b", a)
print(r2)
# ['akjhabsdgfjhabhjgdjabhjgajbkdkjdhfkaab']
# ['akjhab', 'ab', 'ab', 'ajb', 'aab']import re
# # 符号.* 贪婪,匹配从.*前面为开始到后面为结束的所有内容
a = "hfdsakjhabsdgfjhabhjgdjabhjgajbkdkjdhfkaabsdf"
r1= re.findall(r"hfdsak.*?jgdj", a)
print(r1)
r2= re.findall(r"hfdsak(.*?)jgdj", a)
print(r2)
# ['hfdsakjhabsdgfjhabhjgdj']
# ['jhabsdgfjhabh']
# 看到区别了么,就是取出来的数据是否带头尾关于re.S标志的使用说明。
前面的匹配示例中,字符串均不包含换行符。如果待匹配的内容中间包含换行符,默认情况下将无法匹配成功。
多行字符串匹配与re.S标志
import re
a = '''hfdsakjhabsdgfjhabhjgdj
abhjgajbkdkjdhfkaabsdf'''
r1= re.findall(r"hfdsak.*?kjdh", a)
print(r1)
# []
r2= re.findall(r"hfdsak(.*?)jgdj", a,flags=re.S)
print(r2)
# ['jhabsdgfjhabh']正则表达式支持通过可选的标志修饰符来控制匹配行为。这些修饰符通常以可选参数的形式指定。
正则表达式修饰符详解
| 修饰符 | 描述 |
|---|---|
| re.I | 使匹配对大小写不敏感 |
| re.L | 做本地化识别(locale-aware)匹配 |
| re.M | 多行匹配,影响 ^ 和 $ |
| re.S | 使 . 匹配包括换行在内的所有字符 |
| re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
| re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
多个标志可以通过按位或运算符(|)组合使用。例如,设置re.I | re.M即同时启用忽略大小写和多行匹配标志。
补充:实战应用案例。
如果对上述函数和参数的含义已有一定掌握,建议通过具体案例进一步加深理解。接下来将通过几个例子详细说明上述函数的用法:
综合实战案例:提取、替换与分割
# 导入用于正则表达式的re模块
import re
# 取出字符串string8中所有的天气状态
string8 = "{ymd:'2018-01-01',tianqi:'晴',aqiInfo:'轻度污染'},{ymd:'2018-01-02',tianqi:'阴~小雨',aqiInfo:'优'},{ymd:'2018-01-03',tianqi:'小雨~中雨',aqiInfo:'优'},{ymd:'2018-01-04',tianqi:'中雨~小雨',aqiInfo:'优'}"
# 基于正则表达式使用findall函数
print(re.findall("tianqi:'(.*?)'", string8))
# 取出string9中所有含O字母的单词
string9 = 'Together, we discovered that a free market only thrives when there are rules to ensure competition and fair play, Our celebration of initiative and enterprise'
# 基于正则表达式使用findall函数
print(re.findall('w*ow*',string9, flags = re.I))
# 将string10中的标点符号、数字和字母删除
string10 = '据悉,这次发运的4台蒸汽冷凝罐属于国际热核聚变实验堆(ITER)项目的核二级压力设备,先后完成了压力试验、真空试验、氦气检漏试验、千斤顶试验、吊耳载荷试验、叠装试验等验收试验。'
# 基于正则表达式使用sub函数
print(re.sub('[,。、a-zA-Z0-9()]','',string10))
# 将string11中的每个子部分内容分割开
string11 = '2室2厅 | 101.62平 | 低区/7层 | 朝南
上海未来 - 浦东 - 金杨 - 2005年建'
# 基于正则表达式使用split函数
split = re.split('[-|
]', string11)
print(split)
# 分割结果的清洗
split_strip = [i.strip() for i in split]
print(split_strip)
out:
['晴', '阴~小雨', '小雨~中雨', '中雨~小雨']
['Together', 'discovered', 'only', 'to', 'competition', 'Our', 'celebration', 'of']
据悉这次发运的台蒸汽冷凝罐属于国际热核聚变实验堆项目的核二级压力设备先后完成了压力试验真空试验氦气检漏试验千斤顶试验吊耳载荷试验叠装试验等验收试验
['2室2厅 ', ' 101.62平 ', ' 低区/7层 ', ' 朝南 ', ' 上海未来 ', ' 浦东 ', ' 金杨 ', ' 2005年建']
['2室2厅', '101.62平', '低区/7层', '朝南', '上海未来', '浦东', '金杨', '2005年建']
运行结果如下所示:
在第一个示例中,通过正则表达式“tianqi:'(.*?)'”成功获取了目标数据。如果不使用括号,结果将包含完整匹配串,如“tianqi:'晴'”或“tianqi:'阴~小雨'”。添加括号的作用在于定义分组,findall仅返回分组内的内容。
第二个示例中,正则表达式未使用圆括号包裹。若加上圆括号,返回结果依然一致。这说明findall用于返回满足匹配条件的列表值;当存在分组时,仅返回括号内的匹配值。
第三个示例展示了替换功能,将所有标点符号替换为空字符,从而实现删除标点符号的效果。
第四个示例演示了字符串分割。若直接按正则表达式‘[,。、a-zA-Z0-9()]’进行分割,返回结果中会包含空字符,例如‘2室2厅’后可能跟随一个空字符。为了清除列表中每个元素的首尾空格,使用了列表推导式并结合字符串的strip方法完成空字符的去除。
总结。
至此,关于Python中正则表达式findall用法的介绍已完成。如需了解更多相关Python正则表达式内容,请搜索本站历史文章或继续浏览后续文章,感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













