正则表达式(Regular Expression),通常简称为正则或RegExp,是一种强大的文本处理工具,用于匹配、查找和替换字符串中的文本模式。Python 使用内置的 re 模块来支持正则表达式操作。在本教程中,您将了解RegEx并了解各种正则表达式。
import re
pattern = r"Hello"
text = "Hello, World!"
result = re.match(pattern, text)
if result:
print("Match found:", result.group())
else:
print("Match not found")
输出:
Match found: Hello
在开始使用 Python 正则表达式模块之前,让我们看看如何使用元字符或特殊序列实际编写正则表达式。
元字符
为了理解 RE 类比,元字符非常有用、重要,并且将在模块 re 的函数中使用。以下是元字符列表。
元字符 | 含义 |
---|---|
. | 匹配任何字符,除了换行符 \n 。 |
* | 匹配前一个字符或表达式的零次或多次重复。 |
+ | 匹配前一个字符或表达式的一次或多次重复。 |
? | 匹配前一个字符或表达式的零次或一次重复。 |
^ | 匹配字符串的开始。 |
$ | 匹配字符串的结束。 |
[] | 定义字符类,匹配其中任何一个字符。 |
[^] | 在字符类内使用 ^ ,表示匹配除括号内字符之外的任何字符。 |
() | 定义一个子表达式,可以用于捕获或分组匹配。 |
\ | 转义字符,用于取消元字符的特殊含义。 |
{} | 用于指定重复次数的范围。 |
group 方法返回匹配的字符串,start 和 end 方法提供起始和结束字符串索引。除此之外,它还有很多其他的方法。
为什么应该使用正则表达式
- 数据挖掘:正则表达式是数据挖掘的最佳工具。它通过检查预定义的模式来有效地识别文本堆中的文本。一些常见的场景是从一堆文本中识别电子邮件、URL 或电话。
- 数据验证:正则表达式可以完美验证数据。它可以通过定义不同的模式集来包含各种验证过程。一些例子是验证电话号码、电子邮件等。
基本的正则表达式
让我们了解一些基本的正则表达式。它们如下:
- 字符类
- 范围
- 否定/取反
- 字符串的开头和结尾
- 任意字符
字符类
字符类允许您将单个字符集与可能的字符集进行匹配。您可以在方括号内提及字符类。下面是一个区分大小写的单词的示例。
import re
print(re.findall(r'[Gg]eeks', 'GeeksforGeeks: \
A computer science portal for geeks'))
输出:
['Geeks', 'geeks']
范围
借助范围模式(例如数字范围(0 到 9)、字符范围(A 到 Z)等)提供了匹配文本的灵活性。字符类中的连字符(-)表示一个范围。
import re
print('Range',re.search(r'[a-zA-Z]', 'x'))
输出:
Range <re.Match object; span=(0, 1), match='x'>
否定^
否定会反转字符类。它将查找除字符类中提到的倒置字符或倒置字符范围之外的匹配项。在下面的例子中,r'[^a-z]’ 表示匹配任何不在小写字母范围(a 到 z)内的字符。
import re
print(re.search(r'[^a-z]', 'c'))
输出:
None
import re
print(re.search(r'G[^e]', 'Geeks'))
输出:
None
特殊序列列表
特殊序列 | 描述 | 例子 | |
---|---|---|---|
\A | 如果字符串以给定字符开头则匹配 | \Afor | for the world |
for geeks | |||
\b | 如果单词以给定字符开头或结尾,则匹配。\b(string) 将检查单词的开头,而 (string)\b 将检查单词的结尾。 | \bge | geeks |
get | |||
\B | 它与 \b 相反,即字符串不应以给定的正则表达式开头或结尾。 | \Bge | together |
forge | |||
\d | 匹配任意十进制数字,相当于集合类[0-9] | \d | 123 |
gee1 | |||
\D | 匹配任意非数字字符,相当于集合类[^0-9] | \D | geeks |
geek1 | |||
\s | 匹配任何空白字符。 | \s | gee ks |
a bc a | |||
\S | 匹配任何非空白字符 | \S | a bd |
abcd | |||
\w | 匹配任何字母数字字符,这相当于类 [a-zA-Z0-9_]。 | \w | 123 |
geeKs4 | |||
\W | 匹配任何非字母数字字符。 | \W | >$ |
gee<> | |||
\Z | 如果字符串以给定的正则表达式结尾则匹配 | ab\Z | abcdab |
abababab |
让我们讨论一下正则表达式引擎提供的一些快捷方式。
- \w – 匹配单词字符
- \d – 匹配数字字符
- \s – 匹配空白字符(空格、制表符、换行符等)
- \b – 匹配零长度字符
import re
print('Geeks:', re.search(r'\bGeeks\b', 'Geeks'))
print('JkhxwforGeeks:', re.search(r'\bGeeks\b', 'JkhxwforGeeks'))
输出:
Geeks: <_sre.SRE_Match object; span=(0, 5), match='Geeks'>
JkhxwforGeeks: None
字符串的开头和结尾
^ 字符选择字符串的开头,$ 字符选择字符串的结尾。
import re
# Beginning of String
match = re.search(r'^Geek', 'Campus Geek of the month')
print('Beg. of String:', match)
match = re.search(r'^Geek', 'Geek of the month')
print('Beg. of String:', match)
# End of String
match = re.search(r'Geeks$', 'JkhxwforGeeks')
print('End of String:', match)
输出:
Beg. of String: None
Beg. of String: <_sre.SRE_Match object; span=(0, 4), match='Geek'>
End of String: <_sre.SRE_Match object; span=(8, 13), match='Geeks'>
任意字符
.字符表示{}字符类之外的任何单个字符。
import re
print('Any Character', re.search(r'p.th.n', 'python 3'))
输出:
Any Character <_sre.SRE_Match object; span=(0, 6), match='python'>
更多正则表达式
可选字符?
正则表达式引擎允许您使用 ? 指定可选字符。它允许字符或字符类出现一次或不出现。
import re
print('Color',re.search(r'colou?r', 'color'))
print('Colour',re.search(r'colou?r', 'colour'))
输出:
Color <_sre.SRE_Match object; span=(0, 5), match='color'>
Colour <_sre.SRE_Match object; span=(0, 6), match='colour'>
重复
重复使您能够重复相同的字符或字符类。考虑一个由日、月和年组成的日期示例。让我们使用正则表达式来标识日期 (mm-dd-yyyy)。
import re
print('Date{mm-dd-yyyy}:', re.search(r'[\d]{2}-[\d]{2}-[\d]{4}','18-08-2020'))
输出:
Date{mm-dd-yyyy}: <_sre.SRE_Match object; span=(0, 10), match='18-08-2020'>
在这里,正则表达式引擎检查两个连续的数字。找到匹配项后,它会移动到连字符。然后,它检查接下来的两个连续数字,并重复该过程。
重复范围{}
import re
print('Three Digit:', re.search(r'[\d]{3,4}', '189'))
print('Four Digit:', re.search(r'[\d]{3,4}', '2145'))
输出:
Three Digit: <_sre.SRE_Match object; span=(0, 3), match='189'>
Four Digit: <_sre.SRE_Match object; span=(0, 4), match='2145'>
在某些情况下,字符重复没有限制。在这种情况下,您可以将上限设置为不定式。一个常见的例子是匹配街道地址。我们来看一下。
import re
print(re.search(r'[\d]{1,}','5th Floor, A-118,\
Sector-136, Suzhou, Jiangsu - 215000'))
输出:
<_sre.SRE_Match object; span=(0, 1), match='5'>
分组()
分组是使用括号将表达式分成组的过程,它允许您获取每个单独的匹配组。
import re
grp = re.search(r'([\d]{2})-([\d]{2})-([\d]{4})', '26-08-2020')
print(grp)
输出:
<_sre.SRE_Match object; span=(0, 10), match='26-08-2020'>
返回整个匹配
re 模块允许您使用group()方法返回整个匹配:
import re
grp = re.search(r'([\d]{2})-([\d]{2})-([\d]{4})','26-08-2020')
print(grp.group())
输出:
26-08-2020
您还可以使用 groups() 方法返回包含各个匹配组的元组:
import re
grp = re.search(r'([\d]{2})-([\d]{2})-([\d]{4})','26-08-2020')
print(grp.groups())
输出:
('26', '08', '2020')
继续。将索引传递给组方法后,您可以仅检索单个组。
import re
grp = re.search(r'([\d]{2})-([\d]{2})-([\d]{4})','26-08-2020')
print(grp.group(3))
输出:
2020
re 模块允许您命名您的组。让我们看一下语法。
import re
match = re.search(r'(?P<dd>[\d]{2})-(?P<mm>[\d]{2})-(?P<yyyy>[\d]{4})',
'26-08-2020')
print(match.group('mm'))
输出:
08
匹配字典
我们已经看到正则表达式如何提供单个组的元组。不仅是元组,它还可以提供单独的匹配作为字典,其中每个组的名称充当字典键。
import re
match = re.search(r'(?P<dd>[\d]{2})-(?P<mm>[\d]{2})-(?P<yyyy>[\d]{4})',
'26-08-2020')
print(match.groupdict())
输出:
{'dd': '26', 'mm': '08', 'yyyy': '2020'}
替换
正则表达式可以替换字符串,并使用 re.sub 方法返回替换后的字符串。当您希望在将其存储到数据库之前避免使用 /、-、. 等字符时,它非常有用。它需要三个参数:
- 正则表达式
- 替换字符串
- 正在搜索的源字符串
让我们看一下下面的代码,它替换了信用卡号中的– 字符。
import re
print(re.sub(r'([\d]{4})-([\d]{4})-([\d]{4})-([\d]{4})',r'\1\2\3\4',
'1111-2222-3333-4444'))
输出:
1111222233334444
编译后的正则表达式
Python正则表达式引擎可以使用compile函数返回编译后的正则表达式(RegEx)对象。该对象有其搜索方法和子方法,开发人员可以在需要时重用它。
import re
regex = re.compile(r'([\d]{2})-([\d]{2})-([\d]{4})')
# search method
print('compiled reg expr', regex.search('26-08-2020'))
# sub method
print(regex.sub(r'\1.\2.\3', '26-08-2020'))
输出:
compiled reg expr <_sre.SRE_Match object; span=(0, 10), match=’26-08-2020′> 26.08.2020
概括
RegEx 是用于数据挖掘和数据验证的强大工具。但是,只要有简单的解决方案,就避免使用正则表达式。而且,当您必须处理复杂的结构(例如重要的文档格式)时,请尝试使用其他满足需求的库。