在Python中,正则表达式是一种强大的工具,可用于匹配和操作字符串。什么是正则表达式? 正则表达式是一种模式匹配语言,用于匹配字符串中的特定模式。这些模式可以是字母、数字、字符组合或其他符号。正则表达式通常用于文本处理、网络编程、数据分析等领域。本教程中,我们将通过学习Python自带的re模块,来实现通过正则表达式对字符串进行各种操作。有兴趣的同学也可查看官方教程
–图片来源AI绘画
1. 正则表达式
正则表达式由普通字符和元字符组成。普通字符就是字母、数字、空格等常见字符;元字符则表示特殊含义,例如点号(.)表示任意字符,星号(*)表示零个或多个前面的字符。
下面是一些常用的元字符及其含义:
- .:匹配任意单个字符
- \d:匹配数字(等价于 [0-9])
- \w:匹配字母、数字、下划线(等价于 [a-zA-Z0-9_])
- \s:匹配空格、制表符、换行符等空白字符
- ^:匹配开头
- $:匹配结尾
- *:匹配前面的字符零次或多次
- +:匹配前面的字符一次或多次
- ?:匹配前面的字符零次或一次
- []:匹配方括号中任意一个字符
- ():将其中的内容作为一个组
例如,正则表达式 \d{3}-\d{4} 匹配一个类似于“123-4567”的电话号码。
2. re模块基本函数
在使用re模块之前,需要先将其导入。可以通过以下方式导入re模块:
import re
2.1 re.match函数
re.match(pattern, string, flags=0)
函数用于尝试从字符串的起始位置匹配一个模式,如果匹配成功,则返回一个匹配对象;否则返回None。其中,pattern表示要匹配的正则表达式,string表示要匹配的字符串,flags表示匹配模式,默认为0。
import re
str1 = 'hello world'
matchObj = re.match(r'hello', str1)
if matchObj:
print("matchObj.group() : ", matchObj.group())
else:
print("No match!!")
输出结果为:
matchObj.group() : hello
2.2 re.search函数
re.search(pattern, string, flags=0)
函数用于在字符串中搜索匹配正则表达式的第一个位置,如果匹配成功,则返回一个匹配对象;否则返回None。其中,pattern表示要匹配的正则表达式,string表示要匹配的字符串,flags表示匹配模式,默认为0。
示例代码:
import re
str1 = 'hello world'
searchObj = re.search(r'world', str1)
if searchObj:
print("searchObj.group() : ", searchObj.group())
else:
print("No match!!")
输出结果为:
searchObj.group() : world
re.match与re.search的区别:
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
2.3 re.findall函数
re.findall(pattern, string, flags=0)
函数用于在字符串中搜索匹配正则表达式的所有子串,并将其以列表形式返回。其中,pattern表示要匹配的正则表达式,string表示要匹配的字符串,flags表示匹配模式,默认为0。
示例代码:
import re
str1 = 'hello world'
findallObj = re.findall(r'l', str1)
print("findallObj : ", findallObj)
输出结果为:
findallObj : ['l', 'l']
另外还有个re.finditer
函数,和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
re.finditer(pattern, string, flags=0)
2.4 re.sub函数
re.sub(pattern, repl, string, count=0, flags=0)函数用于在字符串中查找匹配正则表达式的所有子串,并将其替换为指定的字符串。其中,pattern表示要匹配的正则表达式,repl表示要替换成的字符串,string表示要匹配的字符串,count表示最多替换次数,flags表示匹配模式,默认为0。
示例代码:
import re
str1 = 'hello world'
subObj = re.sub(r'hello', 'hi', str1)
print("subObj : ", subObj)
输出结果为:
subObj : hi world
另外还有re.split
函数, re.split
按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
3.flags的传值
flags传递的值为模式:python提供9种模式供我们选择:
常量 | 简写 | 作用 |
---|---|---|
re.IGNORECASE |
re.I |
进行忽略大小写匹配 |
re.ASCII 或简写为 re.A | re.A | ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII ,而不是Unicode |
re.DOTALL | re.S | DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n。默认模式下.是不能匹配行符\n的。 |
re.MULTILINE | re.M | 多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的 |
re.VERBOSE | re.X | 详细模式,可以在正则表达式中加注解! |
re.LOCALE | re.L | 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效(官方不推荐使用) |
re.UNICODE | re.U | 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python 3 默认字符串已经是Unicode,所以有点冗余 |
re.DEBUG | 显示编译时的debug信息。 | |
re.TEMPLATE | re.T | 用于创建可定制的正则表达式模板,它将正则表达式中可变部分用占位符表示,然后使用substitute方法替换占位符。这样做的好处是可以避免由于特殊字符引起的转义问题,同时也可以方便地从外部传入参数进行替换。 |
4.高级用法
Python正则表达式是一种强大的文本匹配工具,有许多高级用法可以加速你的开发效率。以下是一些常见的高级用法:
4.1 零宽断言
零宽断言是指在一个位置上进行匹配,但不占用实际的字符。常见的有四种类型:
- 正向先行断言:(?=pattern) 匹配紧随其后的pattern。
- 负向先行断言:(?!pattern) 不匹配紧随其后的pattern。
- 正向后行断言:(?<=pattern) 匹配紧靠其前的pattern。
- 负向后行断言:(?<!pattern) 不匹配紧靠其前的pattern。
示例代码:
import re
# 正向先行断言
print(re.findall(r'\d+(?=%)', '100% of users')) # ['100']
# 负向先行断言
print(re.findall(r'\d+(?!%)', '100% of users and 200 apples')) # [10, '200']
# 正向后行断言
print(re.findall(r'(?<=\$)\d+', 'Price: $10,000.00')) # ['10']
# 负向后行断言
print(re.findall(r'(?<!\$)\d+', 'Price: $10,000.00, Quantity: 5')) # ['0', '000', '00', '5']
4.2 回溯引用
回溯引用是指在正则表达式中引用前面已经出现的捕获组。可以通过\g<组号>或\数字来引用捕获组。
示例代码:
import re
# 引用捕获组
print(re.findall(r'(\w+) \1', 'hello hello world')) # ['hello']
# 命名捕获组
pattern = r'(?P<word>\w+) (?P=word)'
print(re.findall(pattern, 'hello hello world')) # ['hello']
4.3 集合操作
集合操作是指在正则表达式中使用集合运算符来匹配多个模式中的任意一个。常用的集合运算符有|(或)、[…](字符集)和[^…](否定字符集)。
示例代码:
import re
# 或运算符
print(re.findall(r'cat|dog', 'I have a cat and a dog')) # ['cat', 'dog']
# 字符集
print(re.findall(r'[aeiou]', 'apple orange pear')) # ['a', 'e', 'o', 'a', 'e', 'e', 'a']
# 否定字符集
print(re.findall(r'[^aeiou]', 'apple orange pear')) # ['p', 'p', 'l', ' ', 'r', 'n', 'g', ' ', 'p', 'r']
4.4 最小匹配
最小匹配是指在正则表达式中使用非贪婪量词来匹配尽可能少的字符。常用的非贪婪量词有*?、+?、??和{m,n}?。
示例代码:
import re
# 非贪婪量词
print(re.findall(r'<.*?>', '<p>hello</p><p>world</p>')) # ['<p>', '</p>', '<p>', '</p>']
4.5 断言条件
断言条件是指在正则表达式中使用(?(条件)yes|no)来根据条件选择匹配的模式。其中,条件可以是一个捕获组的存在或值等条件。
示例代码:
import re
# 捕获组存在
print(re.findall(r'(cat)?(?(1)dog|bird)', 'I have a catdog and a birddog')) # ['cat', '']
# 捕获组值等于某个字符串
print(re.findall(r'(\d+)(?(1)=100|!=100)', '50=100 100!=200')) # ['50']
5.总结
本教程中,我们深入探讨了Python re模块的用法基础语法
在Python中,我们还可以使用re.compile()
函数对正则表达式进行编译,以提高匹配效率。一般情况下,只需要编译一次正则表达式即可重复使用多次。
同样我们介绍了re.match()
和re.search()
函数及他们的区别,可以使用group()
方法获取匹配到的文本。也介绍了re.findall()
、re.finditer()
、re.sub()的简单用法。例如,可以使用re.sub()
函数对匹配到的文本进行替换。其中第一个参数为正则表达式,第二个参数为替换后的文本。例如:re.sub(r'(\d+)-(\d+)-(\d+)', r'\3/\1/\2', date)
将日期格式从YYYY-MM-DD
转换为DD/MM/YYYY
格式。
除了以上这些函数之外,re模块还提供了很多其他的函数,例如split、subn、escape、purge等。本教程就不一一详细介绍了,有兴趣的同学可以自行编程体验一番。总之,正则表达式在Python中的应用非常广泛,熟练掌握正则表达式的语法和相关函数,能够极大地提高文本处理的效率。
[…] 上一篇教程:Python基础教程:正则表达式 […]