Python 正则表达式备忘单
正则表达式通常称为regex,是Python编程中用于模式匹配和文本操作的强大工具。它们允许你基于特定模式搜索、提取和修改文本,因此在数据验证、字符串操作和文本处理等任务中至关重要。
但是,使用正则表达式可能会具有挑战性,特别是对于初学者或不经常使用它们的人来说。记住语法和理解各种元字符和规则可能令人生畏。
为了使你的正则表达式之旅更顺利,我们创建了一份全面的Python 正则表达式备忘单。这份备忘单作为一个方便的参考指南,为你提供了Python正则表达式中最常用的元字符、字符类、量词、锚点、分组、标志、转义序列和特殊字符的快速概述。
注意 :在你的Python脚本中记得导入re模块以使用正则表达式。
常用的元字符
元字符是正则表达式中的特殊字符,它们具有特定的含义,并用于定义模式。理解和使用这些元字符对于有效的模式匹配至关重要。在本节中,我们将探讨Python正则表达式中最常用的元字符。
- 点 (.) - 点元字符匹配除了换行符以外的任意字符。它经常用来表示通配符字符,允许你在给定位置匹配任意字符。
示例
import re
pattern = r"b.ttle"
text1 = "bottle"
text2 = "battle"
text3 = "bottle\n"
match1 = re.search(pattern, text1)
match2 = re.search(pattern, text2)
match3 = re.search(pattern, text3)
print(match1)
print(match2)
print(match3)
输出
<re.Match object; span=(0, 6), match='bottle'>
<re.Match object; span=(0, 6), match='battle'>
<re.Match object; span=(0, 6), match='bottle'>
在上面的例子中,点元字符”.”用于匹配模式b.ttle中的任何字符。它成功匹配了”bottle”和”battle”,但无法匹配”bottle\n”,因为点不能匹配换行字符。
- 插补符号(^)和美元符号($) − 插补符号和美元符号元字符分别表示行的开头和结尾。它们用于将模式锚定在行的开头或末尾。
示例
import re
pattern1 = r"^Python"
pattern2 = r"\d"
text1 = "Python is a powerful language"
text2 = "The price is10"
match1 = re.search(pattern1, text1)
match2 = re.search(pattern2, text2)
print(match1)
print(match2)
输出
<re.Match object; span=(0, 6), match='Python'>
<re.Match object; span=(15, 16), match='0'>
在上面的示例中,插入符号^用于将模式“Python”锚定在行的开头,在text1中成功匹配。美元符号$用于将模式\d(匹配任何数字)锚定在行的末尾,在text2中成功匹配数字“0”。
- 方括号([…]) - 方括号用于创建一个字符类,允许您从一组指定的字符中匹配一个单独的字符。您可以在方括号内包含多个字符或范围。
示例
import re
pattern = r"[aeiou]"
text = "Hello, World!"
matches = re.findall(pattern, text)
print(matches)
输出
['e', 'o', 'o']
在上面的例子中,模式[aeiou]用于匹配文本中的任何元音字符。findall()函数返回找到的所有匹配的列表,在这种情况下是字符’e’、’o’和’o’。
- 管道符 (|) − 管道符用作OR运算符,允许您匹配左侧的模式或右侧的模式。
示例
import re
pattern = r"cat|dog"
text = "I have a cat and a dog"
match = re.search(pattern, text)
print(match)
输出
<re.Match object; span=(9, 12), match='cat'>
在上面的示例中,模式cat|dog匹配”cat”或”dog”。search()函数返回找到的第一个匹配项,这种情况下是”cat”。
这只是Python正则表达式中常用元字符的几个示例。在下一节中,我们将探讨字符类和量词,以进一步增强我们的模式匹配能力。
字符类和量词
字符类和量词在定义正则表达式模式时提供了额外的灵活性和控制能力。在本节中,我们将深入研究这些功能并学习如何有效使用它们。
- 字符类 - 字符类允许您指定一组字符,在模式的特定位置上匹配。它们用方括号[ ]括起来,并提供了一种从定义的集合中匹配任何单个字符的方法。
示例
import re
pattern = r"[aeiou]"
text = "Hello, World!"
matches = re.findall(pattern, text)
print(matches)
输出
['e', 'o', 'o']
在上面的例子中,字符类[a e i o u]匹配文本中的任何元音字符。findall()函数返回找到的所有匹配项的列表,在本例中是字符’e’、’o’和’o’。
- 否定字符类 - 否定字符类允许你匹配任何不在定义集合中的字符。它们以一个插入符号^在字符类的开头表示。
示例
import re
pattern = r"[^aeiou]"
text = "Hello, World!"
matches = re.findall(pattern, text)
print(matches)
输出
['H', 'l', 'l', ',', ' ', 'W', 'r', 'l', 'd', '!']
在上面的例子中,否定的字符类 [^aeiou] 匹配任何不是元音字母的字符。findall() 函数返回找到的所有匹配项组成的列表,其中包括所有的辅音字母和标点符号。
- 量词 − 量词允许你指定应该匹配的模式出现的次数。它们可以应用于单个字符、字符类或者一组模式。 −
.
− 匹配前一个模式出现的零次或多次。-
+
− 匹配前一个模式出现的一次或多次。 -
?
− 匹配前一个模式出现的零次或一次。 -
{n}
− 匹配前一个模式恰好出现 n 次。 -
{n,}
− 匹配前一个模式至少出现 n 次。 -
{n,m}
− 匹配前一个模式出现 n 到 m 次。
示例
import re
pattern = r"ab*c"
text1 = "ac"
text2 = "abc"
text3 = "abbbbc"
match1 = re.search(pattern, text1)
match2 = re.search(pattern, text2)
match3 = re.search(pattern, text3)
print(match1)
print(match2)
print(match3)
输出
<re.Match object; span=(0, 2), match='ac'>
<re.Match object; span=(0, 3), match='abc'>
<re.Match object; span=(0, 6), match='abbbbc'>
在上面的例子中,量词*
用于匹配模式ab*c
中字符’b’出现零次或多次的情况。它成功匹配了”ac”,”abc”和”abbbbc”,因为’b’字符是可选的。 通过结合字符类、否定字符类和量词,您可以创建强大而灵活的正则表达式模式,以匹配给定文本中的各种模式。 在下一节中,我们将探讨Python正则表达式的更高级特性,包括捕获组、锚点和前向断言。 捕获组、锚点和前向断言是Python正则表达式的高级特性,它们可以提供更多对模式匹配的控制。在本节中,我们将探讨这些特性并了解如何有效使用它们。 捕获组允许您在较大的模式中定义子模式并提取匹配的内容。它们使用括号( )进行定义,并且在您想要提取匹配的特定部分时非常有用。 例子:
import re
pattern = r"(\d{2})-(\d{2})-(\d{4})"
text = "Date of Birth: 01-23-1990"
match = re.search(pattern, text)
if match:
day = match.group(1)
month = match.group(2)
year = match.group(3)
print(f"Day: {day}, Month: {month}, Year: {year}")
输出
Day: 01, Month: 23, Year: 1990
在上面的例子中,模式(\d{2})-(\d{2})-(\d{4})
定义了三个捕获组来匹配日期格式中的日、月和年。search()函数返回一个匹配对象,group()方法用于提取匹配的值。输出将是”Day: 01, Month: 23, Year: 1990″。
- 锚点 - 锚点用于指定在文本中匹配应出现的位置。它们不匹配任何字符,而是断言关于周围文本的条件。两个常用的锚点是^和$。
^
- 匹配字符串的开头。-
$
- 匹配字符串的结尾。
示例
import re
pattern = r"^Python"
text = "Python is a popular programming language"
match = re.search(pattern, text)
if match:
print("Match found!")
else:
print("No match found.")
输出
Match found!
在上面的例子中,模式 ^Python
只会匹配文本开头的单词 “Python”。由于文本以 “Python” 开头,找到了一个匹配,打印出相应的消息。
- 前瞻断言 − 前瞻断言用于指定在模式后面必须满足的条件才能匹配。正向前瞻断言用
(?=...)
表示,负向前瞻断言用(?!...)
表示。
示例
import re
pattern = r"\b\w+(?=ing\b)"
text = "Walking is good for health"
matches = re.findall(pattern, text)
print(matches)
输出
['Walk']
在上面的示例中,模式\b\w+(?=ing\b)
匹配任何在后面跟着后缀”ing”的单词。正向先行断言(?=ing\b)断定该单词应该在后面跟着”ing”,但它不是实际匹配的一部分。findall()函数返回一个包含所有匹配单词的列表,这里的匹配单词是”Walk”。
通过利用捕获组、锚点和先行断言,您可以创建更复杂的正则表达式模式,精确匹配和提取文本中的特定内容。
在下一节中,我们将探讨Python正则表达式的其他高级功能,包括后向引用、标志和高级修饰符。
后向引用、标志和高级修饰符
后向引用、标志和高级修饰符是增强Python正则表达式模式匹配能力的强大功能。在本节中,我们将深入了解这些功能,并学习如何有效地利用它们。
- 后向引用 − 后向引用允许您在模式中引用先前捕获的组。它们用反斜杠\后跟组号或组名来表示。后向引用在匹配重复模式或确保匹配内容的一致性时非常有用。
示例
import re
pattern = r"(\w+)\s+\1"
text = "hello hello"
match = re.search(pattern, text)
if match:
print("Match found!")
else:
print("No match found.")
产出
Match found!
在上面的例子中,模式(\w+)\s+\1
匹配一个单词,后面跟着一个或多个空格,然后再次出现相同的单词。反向引用\1
指的是第一个捕获的分组,从而确保重复相同的单词。由于文本中包含”hello hello”,因此找到了一个匹配,并打印相应的消息。
- Flags - 标志修改正则表达式模式匹配的行为。它们使用re模块的常量表示,并可以作为可选参数传递给正则表达式函数。一些常用的标志包括: –
- re.IGNORECASE - 在匹配时忽略大小写。
- re.MULTILINE - 启用多行匹配。
- re.DOTALL - 允许点(.)匹配任何字符,包括换行符。
示例
import re
pattern = r"python"
text = "Python is a popular programming language"
match = re.search(pattern, text, re.IGNORECASE)
if match:
print("Match found!")
else:
print("No match found.")
结果
Match found!
在上面的示例中,使用re.IGNORECASE标志将模式python与文本匹配。结果是忽略大小写差异,并且尽管单词”Python”以大写字母开头,但仍然找到匹配项。
Advanced Modifiers
- 高级修饰符 - 高级修饰符提供对正则表达式匹配行为的额外控制。它们是使用特殊字符放置在正则表达式模式的闭合分隔符之后来表示的。
?
- 使前面的模式可选(匹配 0 或 1 次出现)。-
.
- 匹配前面的模式的 0 或多次出现。 -
+
- 匹配前面的模式的 1 或多次出现。 -
{m}
- 匹配前面的模式恰好 m 次出现。 -
{m, n}
- 匹配前面的模式在 m 和 n 之间的次数出现。
示例
import re
pattern = r"apples?|bananas?"
text = "I like apple and bananas"
matches = re.findall(pattern, text)
print(matches)
输出
['apple', 'bananas']
在上面的例子中,模式apples?|bananas?匹配“apple”或“apples”以及“banana”或“bananas”。?修饰符使前面的字符或组变为可选,可以匹配水果名称的单数和复数形式。 通过使用反向引用、标志和高级修饰符,您可以创建更灵活和动态的正则表达式模式来处理各种匹配场景。 在下一节中,我们将讨论常见的正则表达式陷阱和最佳实践,以提高您的正则表达式技巧。 常见的正则表达式陷阱和最佳实践 正则表达式是强大的模式匹配工具,但如果使用不当,也容易出现问题。在本节中,我们将探讨一些常见的陷阱,并提供最佳实践,帮助您避免它们。 贪婪匹配与非贪婪匹配 一个常见的陷阱是正则表达式的贪婪匹配行为,其中模式会尽可能匹配尽量多的内容。这可能会导致意外的结果,特别是在使用*
和+
等量词时。为了减轻这个问题,您可以使用非贪婪修饰符*?
和+?
来尽可能匹配尽量少的内容。 示例
import re
text = "<html><body><h1>Title</h1></body></html>"
pattern = r"<.*?>"
matches = re.findall(pattern, text)
print(matches)
输出
['<html>', '<body>', '<h1>', '</h1>', '</body>', '</html>']
在上面的例子中,模式<.*?>
匹配HTML标签。.*?
非贪婪修饰符保证匹配停止在第一个>出现的位置。如果没有非贪婪修饰符,匹配将跨越整个文本,包括多个标签。
- 锚定匹配 - 锚定匹配可以防止在文本中意外位置出现的非预期的匹配。锚点是特殊字符,用于标记行的开头 (
^
) 和结尾 ($
) 或整个文本的开头和结尾。
示例
import re
text = "The quick brown fox jumps over the lazy dog."
pattern = r"\bfox\b"
matches = re.findall(pattern, text)
print(matches) # Output: ['fox']
输出
['fox']
在上面的例子中,模式\bfox\b匹配整个单词”fox”。\b
锚点确保”fox”不会作为其他单词的一部分匹配,比如”foxy”或者”foxes”。
- 复杂的嵌套模式当处理涉及嵌套分组的复杂模式时,重要的是使用命名分组和适当的模式组织以提高可读性和可维护性。
示例
import re
text = "Date: 2022-01-01, Time: 12:00 PM"
pattern = r"Date: (?P<date>\d{4}-\d{2}-\d{2}), Time: (?P<time>\d{2}:\d{2} [AP]M)"
match = re.search(pattern, text)
if match:
date = match.group("date")
time = match.group("time")
print(f"Date: {date}, Time: {time}")
输出
Date: 2022-01-01, Time: 12:00 PM
在上面的例子中,模式使用命名组(?P<name>pattern)
来捕获日期和时间信息。这种方法提高了代码的可读性,并允许使用组名轻松访问捕获的值。
结论
正则表达式是Python中用于模式匹配和文本操作的强大工具。通过理解基本语法、元字符和常见的正则表达式技巧,您可以解锁处理文本数据的各种可能性。