为什么在Python正则表达式中使用问号文字?

为什么在Python正则表达式中使用问号文字?

阅读更多:Python 教程

简介

问号使正则表达式中的前一个标记为可选项。例如:colou?r对都适用的是colour和color。一个量词就是所谓的问号。

通过将多个标记组合在括号中,并在最后一组括号后加上问号,您可以使多个标记可选。例如,Nov(ember)?匹配Nov和Nov之间的日期。

使用许多问号,您可以创建一个正则表达式,匹配各种选项。Feb(ruary)? 23(rd)? 匹配February 23rd、February 23、Feb 23rd和Feb 23。

花括号也可用于使某物成为可选项。colou?r的等效形式为colou{0,1}r。POSIX BRE和GNU BRE都与其他正则表达式不兼容。花括号需要反斜杠来表示以下风格的特定含义:colou\{0,1\}r。

重要的正则表达式概念:贪婪度

本课程介绍的第一个贪婪元字符是问号。对于问号,正则表达式引擎有两个选项:要么尝试匹配问号所涉及的部分,要么不尝试匹配它。该引擎总是尝试匹配该组件。该引擎不会尝试忽略问号所涉及的部分,除非这导致完整的正则表达式失败。

因此,当应用正则表达式Feb 23(rd)?到文本Today is Feb 23, 2003时,匹配总是Feb 23rd,而不是Feb 23。通过在第一个问号后添加另一个问号,您可以使问号变成“懒惰的”(即,关闭贪婪度)。

语法

re.findall():re.findall(pattern, string)

方法在字符串中查找所有pattern
出现的位置,并返回所有匹配子字符串的列表。

第一个参数是正则表达式模式“aa[cde]?”。要检查模式的字符串是第二个参数。简单来说,您正在寻找以两个“a”字符开头和一个可选字符“c”、“d”或“e”的模式。

示例

# 载入re模块
import re
# 由findall函数执行
result1 = re.findall('aa[cde]?', 'aacde aa aadcde')
# re.findall(pattern, string)方法在字符串中查找所有pattern出现的位置,并返回所有匹配子字符串的列表。
result2 = re.findall('aa?', 'accccacccac')
result3 = re.findall('[cd]?[cde]?', 'ccc dd ee')
# 打印结果
print(result1)
print(result2)
print(result3)

输出

['aac', 'aa', 'aad']
['a', 'a', 'a']
['cc', 'c', '', 'dd', '', 'e', 'e', '']

代码解释

findall()方法返回三个匹配的子字符串:

首先,模式与字符串“aac”匹配。在Python匹配子字符串后,子字符串仍然为“de aa aadcde”。此外,字符串“aa”匹配模式。它被Python消耗掉,留下了仅为“aadcde”的子字符串。第三个,最后的子字符串中的模式匹配字符串“aad”。留下“cde”,不再有匹配的子字符串。

查看正则表达式引擎内部

现在将模式colou?r应用于字符串The colonel likes the colour green。

字面上的 c 是正则表达式中的第一个标记。在 colonel 中的 c 是它正确匹配的第一个位置。引擎继续运行,发现 l 匹配 l,另一个 o 匹配 o,o 再次匹配 o。然后引擎确定 u 和 n 是否相等。它失败了。然而,问号指示正则表达式引擎允许缺少字符 u。因此,引擎继续进行到下一个正则表达式标记 r。然而,这也无法匹配 n。现在,引擎只能得出结论,从 colonel 中的 c 开始的整个正则表达式无法匹配。为了匹配 colonel 中的 c 到第一个 o,引擎重新启动。

o、l 和 o在一系列失败后匹配了以下字符, c 匹配了颜色中的 c。引擎现在确定 u 和 r 是否匹配。它失败了。同样,没有问题。由于问号的缘故,引擎可能继续执行 r。引擎声明,正则表达式成功匹配了我们文本中的颜色,因为它匹配了 r。

结论

当应用于正则表达式 A 时,Python 的 A?量词匹配零个或一个 A 的实例。例如,常规短语 “hey?” 匹配字符串 “he” 和 “hey”,但不匹配空字符串 “。” 这是因为?量词仅应用于它之前的正则表达式 ‘y’,而不应用于整个正则表达式’,hey’。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程