在 Python 2 中使用正则表达式

如果您需要复习正则表达式的使用方法,请先查看我们的 交互式教程

Python 通过标准 Python 库 re 支持正则表达式,该库包含在每个 Python 安装中。虽然此库并不完全兼容 PCRE,但它支持正则表达式的大多数常见用例。

原始 Python 字符串

在 Python 中编写正则表达式时,建议使用 原始字符串 而不是常规 Python 字符串。原始字符串以特殊前缀 (r) 开头,并指示 Python 不要解释字符串中的反斜杠和特殊元字符,从而允许您将它们直接传递给正则表达式引擎。

这意味着像 "\n\w" 这样的模式将不会被解释,并且可以写成 r"\n\w" 而不是像其他语言那样写成 "\\n\\w",这更容易阅读。

匹配字符串

re 包含许多顶级方法,要测试正则表达式是否与 Python 中的特定字符串匹配,可以使用 re.search()。如果模式不匹配,则此方法返回 None,否则返回一个 re.MatchObject,其中包含有关在字符串的哪个部分找到匹配项的附加信息。

请注意,此方法在第一次匹配后停止,因此它最适合测试正则表达式而不是提取数据。

方法
matchObject = re.search(pattern, input_str, flags=0)
示例
import re # 让我们使用正则表达式来匹配日期字符串。忽略 # 输出,因为我们只是在测试正则表达式是否匹配。 regex = r"([a-zA-Z]+) (\d+)" if re.search(regex, "June 24"): # 确实,表达式 "([a-zA-Z]+) (\d+)" 匹配日期字符串      # 如果需要,我们可以使用 MatchObject 的 start() 和 end() 方法 # 来检索模式在输入字符串中匹配的位置,以及 # group() 方法获取所有匹配项和捕获的组。 match = re.search(regex, "June 24")      # 这将打印 [0, 7),因为它从字符串的开头到结尾匹配 # 字符串 print "Match at index %s, %s" % (match.start(), match.end())      # 组包含匹配的值。特别是: # match.group(0) 始终返回完全匹配的字符串 # match.group(1)、match.group(2)、... 将按顺序返回捕获 # 从输入字符串中从左到右的组 # match.group() 等效于 match.group(0)      # 因此这将打印“June 24” print "Full match: %s" % (match.group(0)) # 因此这将打印“June” print "Month: %s" % (match.group(1)) # 因此这将打印“24” print "Day: %s" % (match.group(2)) else: # 如果 re.search() 没有匹配,则返回 None print "The regex pattern does not match. :("

捕获组

与上面的 re.search() 方法不同,我们可以使用 re.findall() 在整个输入字符串上执行全局搜索。如果模式中存在捕获组,则它将返回所有捕获数据的列表,否则,它将只返回匹配项本身的列表,或者如果未找到匹配项则返回空列表。

如果您需要每个匹配项的其他上下文,则可以使用 re.finditer(),它返回 re.MatchObjects 的迭代器以进行遍历。这两种方法都采用相同的参数。

方法
matchList = re.findall(pattern, input_str, flags=0)
matchList = re.finditer(pattern, input_str, flags=0)
示例
import re # 让我们使用正则表达式来匹配一些日期字符串。 regex = r"[a-zA-Z]+ \d+" matches = re.findall(regex, "June 24, August 9, Dec 12") for match in matches: # 这将打印: # June 24 # August 9 # Dec 12 print "Full match: %s" % (match) # 要捕获每个日期的特定月份,我们可以使用以下模式 regex = r"([a-zA-Z]+) \d+" matches = re.findall(regex, "June 24, August 9, Dec 12") for match in matches: # 这现在将打印: # June # August # Dec print "Match month: %s" % (match) # 如果我们需要每个匹配的确切位置 regex = r"([a-zA-Z]+) \d+" matches = re.finditer(regex, "June 24, August 9, Dec 12") for match in matches: # 这现在将打印: # 0 7 # 9 17 # 19 25 # 这对应于输入字符串中每个匹配的开始和结束位置 print "Match at index: %s, %s" % (match.start(), match.end())

查找和替换字符串

另一个常见任务是使用正则表达式查找和替换字符串的一部分,例如,替换旧电子邮件域的所有实例,或交换某些文本的顺序。您可以在 Python 中使用 re.sub() 方法执行此操作。

可选的 count 参数是要在输入字符串中进行替换的确切次数,如果此值为零或小于零,则替换字符串中的每个匹配项。

方法
replacedString = re.sub(pattern, replacement_pattern, input_str, count, flags=0)
示例
import re # 让我们尝试反转日期字符串中日期和月份的顺序 # 字符串。请注意,替换字符串也包含元字符 # (对捕获组的反向引用),因此我们也对该字符串使用原始 # 字符串。 regex = r"([a-zA-Z]+) (\d+)" # 这将重新排序字符串并打印: # 24 of June, 9 of August, 12 of Dec print re.sub(regex, r"\2 of \1", "June 24, August 9, Dec 12")

re 标志

在上面的 Python 正则表达式方法中,您会注意到它们都带有一个可选的 flags 参数。大多数可用的标志都是为了方便,可以将其直接写入正则表达式本身,但在某些情况下,有些标志很有用。

  • re.IGNORECASE 使模式不区分大小写,以便它匹配不同大小写形式的字符串
  • re.MULTILINE 如果您的输入字符串包含换行符 (\n),则此标志是必需的,此标志允许开始和结束元字符 (^$ 分别) 在每行的开头和结尾匹配,而不是在整个输入字符串的开头和结尾匹配
  • re.DOTALL 允许点 (.) 元字符匹配所有字符,包括换行符 (\n)

编译模式以提高性能

在 Python 中,创建新的正则表达式模式以匹配许多字符串可能很慢,因此建议如果您需要使用相同的表达式测试或从许多输入字符串中提取信息,则编译它们。此方法返回一个 re.RegexObject

regexObject = re.compile(pattern, flags=0)

返回的对象与上面完全相同的方法,除了它们接受输入字符串并且不再需要每次调用都提供模式或标志。

import re # 让我们创建一个模式并用它提取一些信息 regex = re.compile(r"(\w+) World") result = regex.search("Hello World is the easiest") if result: # 这将打印: # 0 11 # 匹配的开始和结束位置 print result.start(), result.end() # 这将打印: # Hello # Bonjour # 每个匹配的捕获组 for result in regex.findall("Hello World, Bonjour World"): print result # 这将把“World”替换为“Earth”并打印: # Hello Earth print regex.sub(r"\1 Earth", "Hello World")

链接

有关在 Python 中使用正则表达式的更多信息,请访问以下链接