正则表达式(Regular Expression)是字符串处理的一把利器,在Python中通过内置的re库即可调用。它能够快速完成文本匹配、提取、替换等操作,广泛应用于数据清洗、表单验证、日志解析等场景。本文从基础匹配函数讲起,逐步深入到语法规则、贪婪与非贪婪模式、组与或的使用以及预编译与替换,并附带可直接运行的代码示例。
一、核心匹配函数:match、search、findall
re库提供了三个最常用的匹配函数:match()、search()和findall()。
1. match():从字符串起始位置开始匹配,如果开头不符合规则,直接返回None。成功时返回匹配对象,包含起始位置和内容。
- import re
- message = '张三、李四、王五、赵六'
- result = re.match('张三', message)
- print(result) # 匹配成功,输出匹配对象
- result = re.match('李四', message)
- print(result) # None,因为'李四'不在开头
复制代码
2. search():扫描整个字符串,返回第一个匹配结果,不限制起始位置。效果类似于在文本中查找。
- import re
- message = '张三、李四、王五、赵六'
- result = re.search('王五', message)
- print(result) # 匹配成功,即使'王五'不在开头
复制代码
3. findall():找出字符串中所有符合规则的子串,以列表形式返回。
- import re
- message = '张三、李四、王五、赵六、王五'
- result = re.findall('王五', message)
- print(result) # ['王五', '王五']
复制代码
二、正则表达式语法规则
1. 字符范围
字符集用方括号表示,可匹配指定范围内的任意单个字符。
- import re
- message = 'Python93,C87,Java63,C++88'
- # 匹配第一个出现的'c'或'n'
- print(re.search('[cn]', message)) # 匹配到'P'? 误,实际匹配到'n'
- # 提取所有数字
- print(re.findall('[0-9]', message))
- # 提取由字母后跟数字组成的两位结果
- print(re.findall('[cn][0-9]', message)) # 匹配'C8','J6'? 注意大小写
复制代码
2. 匹配次数
常用量词:*(0次或多次)、+(1次或多次)、?(0次或1次)、{n}(恰好n次)、{n,}(至少n次)、{n,m}(n到m次)。它们控制前面元素出现的次数。
- import re
- message = 'da2a7ddbre77yifed777t3fefd7777b'
- # 匹配字母(0次或多次)后紧跟一个数字再跟一个字母
- result = re.findall('[a-z]*[0-9][a-z]', message)
- print(result)
复制代码
实际应用:手机号、QQ号、用户名验证。
- import re
- # 手机号:以1开头,后跟10位数字
- phone = input('请输入手机号:')
- if re.fullmatch('1[0-9]{10}', phone): # fullmatch要求完全匹配
- print('有效手机号')
- else:
- print('无效')
- # QQ号:首位1-9,后跟4-10位数字
- qq = input('请输入QQ号:')
- if re.match('[1-9][0-9]{4,10}$', qq):
- print('有效QQ')
- else:
- print('无效')
- # 用户名:以字母或下划线开头,后跟至少7个单词字符(字母、数字、下划线)
- username = input('请输入用户名:')
- if re.match('^[A-Za-z_]\w{7,}$', username):
- print('有效用户名')
- else:
- print('无效')
复制代码
3. 特殊字符
\d(数字)、\w(单词字符)、\s(空白)、\b(单词边界)等,能简化常用的匹配模式。
- import re
- message = 'verb very never every'
- # 匹配单词结尾为er但后面不能是单词边界的词(即er在单词中间)
- print(re.findall(r'\w+er\B', message))
- # 匹配任意字符后跟'e'
- print(re.findall('.e', message))
复制代码
三、贪婪与非贪婪模式
默认情况下,量词采用贪婪模式,尽可能匹配更多字符。在量词后加?可切换为非贪婪模式,匹配尽可能少的字符。
- import re
- message = 'ccc739134792hd'
- print(re.findall('ccc\d+', message)) # 贪婪:匹配所有数字
- print(re.findall('ccc\d+?', message)) # 非贪婪:只匹配第一个数字'7'
复制代码
四、或(|)与分组(())
| 用于逻辑或,匹配左侧或右侧的表达式。用圆括号可以将部分内容定义为组,组内匹配的内容会被保存,便于后续提取。
- import re
- message = 'verb very never every'
- # 匹配包含'ev'或'ry'的单词
- print(re.findall('\w+ev|\w+ry', message))
- # 使用分组捕获:取出e后面的字符直至r
- print(re.findall('e(.+)(.)r', message))
复制代码
五、替换与预编译
1. sub():替换所有匹配到的内容。
- import re
- content = 'dh9322hf9f934hfnf39d'
- content = re.sub('\d', '0', content)
- print(content) # 所有数字变为0
复制代码
2. compile():当同一个正则表达式需要多次使用时,预编译可提升性能。编译后的模式对象拥有相同的方法(search、findall、sub等)。
- import re
- datetime_str = '2020 12 15 12:00'
- pattern = re.compile('\d{2}:\d{2}')
- print(pattern.findall(datetime_str))
复制代码
六、学习建议
正则表达式的语法丰富,不必一开始就记住所有。建议从简单匹配开始,逐步增加复杂度。使用在线工具(如Regex101)调试验证规则,直观看到匹配过程。先分析待匹配文本的规律,再转化为正则表达式。日常多写多练,常用语法自然记牢。
掌握以上内容,已能应对Python字符串处理中的多数正则需求。实际开发中,结合具体场景灵活组合匹配函数与语法规则,能大幅提高文本处理效率。 |