1. 正则表达式介绍
正则表达式是一种匹配字符串的模式。在Python中,通过re模块可以使用正则表达式进行字符串的匹配。在正则表达式中,通常用某些特定的字符来编写模式,这些字符具有特殊的匹配规则,比如用于匹配数字、字母、空格等。例如,以下是使用正则表达式匹配字符串中的数字:
import re
string = 'abc123def'
pattern = r'\d'
result = re.findall(pattern, string)
print(result)
在这个例子中,使用re.findall函数来匹配字符串中的数字,其中模式r'\d'代表匹配数字,最后返回匹配结果[1, 2, 3]。下面我们将更详细地介绍re模块的相关知识。
2. re模块常用函数
2.1 re.match函数
re.match函数用于从字符串的开头进行正则表达式匹配。例如,以下是使用re.match函数匹配字符串中的数字:
import re
string = 'abc123def'
pattern = r'\d'
result = re.match(pattern, string)
print(result)
在这个例子中,使用re.match函数来匹配字符串中的数字,然而结果为None。这是因为re.match只会从字符串的开头进行匹配,而字符串的开头并不是数字。如果将pattern改为r'abc',那么匹配结果为re.Match对象,表示匹配成功。
2.2 re.search函数
re.search函数用于在字符串中查找正则表达式匹配,如果找到,则返回re.Match对象。例如,以下是使用re.search函数匹配字符串中的数字:
import re
string = 'abc123def'
pattern = r'\d'
result = re.search(pattern, string)
print(result)
在这个例子中,使用re.search函数来匹配字符串中的数字,最后返回re.Match对象,表示匹配成功。如果匹配失败,则返回None。
2.3 re.findall函数
re.findall函数用于匹配字符串中的所有符合正则表达式的子串,并将这些子串存放在一个列表中返回。例如,以下是使用re.findall函数匹配字符串中的数字:
import re
string = 'abc123def'
pattern = r'\d'
result = re.findall(pattern, string)
print(result)
在这个例子中,使用re.findall函数来匹配字符串中的数字,最后返回[1, 2, 3],表示匹配成功。
2.4 re.sub函数
re.sub函数用于替换字符串中符合正则表达式的子串。例如,以下是使用re.sub函数将字符串中的数字替换成问号:
import re
string = 'abc123def'
pattern = r'\d'
result = re.sub(pattern, '?', string)
print(result)
在这个例子中,使用re.sub函数将字符串中的数字替换成问号,最后返回'abc???def'。re.sub函数的第三个参数可以控制替换的次数,如果省略该参数,则默认替换所有符合正则表达式的子串。
2.5 re.compile函数
re.compile函数用于将正则表达式编译成一个对象,从而可以重复使用。例如,以下是使用re.compile函数进行正则表达式匹配的例子:
import re
string1 = 'abc123def'
string2 = 'aaa456bbb'
pattern = r'\d'
regex = re.compile(pattern)
result1 = regex.findall(string1)
result2 = regex.findall(string2)
print(result1)
print(result2)
在这个例子中,使用re.compile函数将正则表达式编译成一个对象regex,然后分别使用该对象匹配string1和string2字符串。最后返回结果[1, 2, 3]和[4, 5, 6],表示匹配成功。re.compile函数还可以接受一些可选参数,用于对正则表达式的匹配规则进行自定义。
3. re模块中的元字符和特殊序列
在正则表达式中,使用一些特定的字符来编写模式,这些字符具有特殊的匹配规则,我们称它们为元字符。另外,正则表达式还包含一些特殊序列,用于匹配特定的字符。在Python的re模块中,常用的元字符和特殊序列有:
3.1 元字符
元字符是正则表达式中的特殊字符,用于匹配字符串中的某些字符。以下是一些常用的元字符:
.:匹配任意字符,除了换行符。
^:匹配字符串的开头。
$:匹配字符串的结尾。
*:匹配前面的字符出现0次或多次。
+:匹配前面的字符出现1次或多次。
?:匹配前面的字符出现0次或1次。
{}:匹配前面的字符出现指定次数。
[]:匹配括号中的任意一个字符。
|:表示“或”关系。
():表示一个整体。
例如,以下是使用不同的元字符进行字符串匹配的例子:
import re
string1 = 'abc123def'
string2 = 'abcABC123DEF'
string3 = 'abcdef'
# 匹配任意字符
pattern1 = r'.'
result1 = re.findall(pattern1, string1)
print(result1) # ['a', 'b', 'c', '1', '2', '3', 'd', 'e', 'f']
# 匹配字符串开头
pattern2 = r'^abc'
result2 = re.findall(pattern2, string1)
print(result2) # ['abc']
# 匹配字符串结尾
pattern3 = r'def$'
result3 = re.findall(pattern3, string1)
print(result3) # ['def']
# 匹配0到多个重复字符
pattern4 = r'[a-z]*'
result4 = re.findall(pattern4, string1)
print(result4) # ['abc', '', '', '', 'def', '']
# 匹配1到多个重复字符
pattern5 = r'[a-z]+'
result5 = re.findall(pattern5, string1)
print(result5) # ['abc', 'def']
# 匹配0到1个重复字符
pattern6 = r'\d?'
result6 = re.findall(pattern6, string2)
print(result6) # ['a', 'b', 'c', 'A', 'B', 'C', '', '1', '2', '3', 'D', 'E', 'F', '']
# 匹配指定次数的重复字符
pattern7 = r'[a-z]{3}'
result7 = re.findall(pattern7, string3)
print(result7) # ['abc', 'def']
3.2 特殊序列
特殊序列是正则表达式中与特定字符匹配的处理方式。以下是一些常用的特殊序列:
\d:匹配任意数字,等价于[0-9]。
\D:匹配任意非数字,等价于[^0-9]。
\w:匹配任意字母数字下划线,等价于[a-zA-Z0-9_]。
\W:匹配任意非字母数字下划线,等价于[^a-zA-Z0-9_]。
\s:匹配任意空白字符,包括空格、制表符、换行符等。
\S:匹配任意非空白字符。
例如,以下是使用不同的特殊序列进行字符串匹配的例子:
import re
string1 = 'abc123def'
string2 = 'abc\t123\nxyz'
# 匹配数字
pattern1 = r'\d'
result1 = re.findall(pattern1, string1)
print(result1) # ['1', '2', '3']
# 匹配非数字
pattern2 = r'\D'
result2 = re.findall(pattern2, string1)
print(result2) # ['a', 'b', 'c', 'd', 'e', 'f']
# 匹配字母数字下划线
pattern3 = r'\w'
result3 = re.findall(pattern3, string1)
print(result3) # ['a', 'b', 'c', '1', '2', '3', 'd', 'e', 'f']
# 匹配非字母数字下划线
pattern4 = r'\W'
result4 = re.findall(pattern4, string1)
print(result4) # []
# 匹配空白字符
pattern5 = r'\s'
result5 = re.findall(pattern5, string2)
print(result5) # [' ', '\t', '\n']
# 匹配非空白字符
pattern6 = r'\S'
result6 = re.findall(pattern6, string2)
print(result6) # ['a', 'b', 'c', '1', '2', '3', 'x', 'y', 'z']
4. re模块中的贪婪匹配和非贪婪匹配
在正则表达式中,使用元字符*、+、?和{}时,默认为贪婪匹配,即匹配尽可能多的字符。例如,以下是使用贪婪匹配的例子:
import re
string = 'Tom 18 '
# 贪婪匹配
pattern1 = r'<.*>'
result1 = re.findall(pattern1, string)
print(result1) # ['Tom 18 ']
# 非贪婪匹配
pattern2 = r'<.*?>'
result2 = re.findall(pattern2, string)
print(result2) # ['', ' ', '', ' ']
在这个例子中,使用贪婪匹配的模式r'<.*>'会匹配整个字符串,因为.*会匹配所有字符,直到匹配到最后一个字符。而非贪婪匹配的模式r'<.*?>'会匹配尽可能少的字符,因此会匹配两个
5. re模块中的分组
在正则表达式中,使用圆括号()来创建一个分组,从而可以通过分组来对字符串进行匹配。例如,以下是使用分组进行字符串匹配的例子:
import re
string = 'Tom 18 '
# 使用分组
pattern = r'(.*) (.*) '
result = re.findall(pattern, string)
print(result) # [('Tom', '18')]
在这个例子中,使用分组的模式r'
6. re模块中的替换
在re模块中,使用re.sub函数可以对字符串中符合正则表达式的子串进行替换。该函数接受三个参数,第一个参数为正则表达式,第二个参数为要替换成的字符串,第三个参数为原字符串。例如,以下是使用re.sub函数进行字符串替换的例子:
import re
string1 = 'abc123def'
string2 = 'aaa456bbb'
pattern = r'\d'
replacement = '?'
# 替换所有符合正则表达式的子串
result1 = re.sub(pattern, replacement, string1)
result2 = re.sub(pattern, replacement, string2)
print(result1) # abc???def
print(result2) # aaa???bbb
# 只替换前两个符合正则表达式的子串
result3 = re.sub(pattern, replacement, string1, count=2)
result4 = re.sub(pattern, replacement, string2, count=2)
print(result3) # abc??3def
print(result4) # aaa??6bbb
在这个例子中,使用re.sub函数将字符串中的数字替换成问号,如果不指定count参数,则默认替换所有符合正则表达式的子串,否则只替换前count个符合正则表达式的子串。
7. re模块的性能优化
在对大量字符串进行正则表达式匹配时,为了提高程序的性能,可以采用以下几种方法:
尽量使用非贪婪匹配,可以减少匹配的次数。
在正则表达式中使用原始字符串,可以避免转义字符的多次处理。
使用re.compile函数将正则表达式编译成一个对象,可以避免重复解析正则表达式的过程。
在正则表达式中,尽量使用[]替换.*,可以减少匹配的范围。
使用越精确的正则表达式,匹配的速度就越快。
下面是使用以上优化方法的例子:
import re
# 尽量使用非贪婪匹配,可以减少匹配的次数
string = 'abc123def'
pattern1 = r'<.*>'
pattern2 = r'<.*?>'
result1 = re.findall(pattern1, string)
result2 = re.findall(pattern2, string)
print(result1) # ['abc123def']
print(result2) # []
# 在正则表达式中使用