返回意外结果的 Python 3 正则表达式

标签 python regex

我不明白为什么后面的两个代码块会为测试用例提供不同的结果。第一个代码块按预期返回 2016,但当进行小的更改时,第二个代码块返回 None。

这是第一个,按预期返回“2016”

import re
date = '24 Jan 2016'
def func(line):
    month_regex = re.search('(\d{1,2})\s(Jan)\s(\d{2,4})', line)
    if month_regex:
        year = month_regex.group(3)
    return year
func(date)

然后,我添加“(uary)?”到正则表达式,由于某种原因,它返回 None。请注意,group(1) 和 group(2) 在这两种情况下的结果相同。

import re
date = '24 Jan 2016'
def func(line):
    month_regex = re.search('(\d{1,2})\s(Jan(uary)?)\s(\d{2,4})', line)
    if month_regex:
        year = month_regex.group(3)
    return year
func(date)

为什么第二个代码块返回 None?

最佳答案

由于第二个正则表达式包含一个额外的 (uary)? capturing 组,匹配结果现在包含 4 个组和 .group(3) 不再映射到年份,而是映射到可选的 uary 子字符串。并且由于输入在 Jan 之后没有 uary,因此组值为 None,它只是未初始化。

在保持组结构不变的同时添加可选组的最佳方法是通过 non-capturing groups :

month_regex = re.search(r'(\d{1,2})\s(Jan(?:uary)?)\s(\d{2,4})', line)
                                         ^^ 

参见 Python demo online .

这里,分组如下:

(\d{1,2})\s(Jan(?:uary)?)\s(\d{2,4})
|-- 1 --|  |---- 2 -----|  |-- 3 --|

此外,最佳做法是使用原始字符串文字进行正则表达式模式声明,只是为了避免在添加单词边界或反向引用时产生进一步的误解。

关于返回意外结果的 Python 3 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45508971/

相关文章:

并行的 Python 线性回归 - Scoop

python - 谁使用 tf.estimator.train_and_evaluate 提前停止评估损失?

python - 为什么gunicorn会显示一个额外的进程?

python - 使用正则表达式从 URL 捕获域和路径

Python 3.7 - 连接字符串并将其写入磁盘的快速方法

python - 使用非默认 Apache Web 服务器编译 mod_wsgi?

python - 如果组包含换行符,则正则表达式替换不起作用

regex - 忽略目录中除一个子文件夹外的所有内容

Java正则表达式将带引号的字符串与嵌入的转义引号相匹配

java - 正则表达式包含一个或多个电话号码