我不明白为什么后面的两个代码块会为测试用例提供不同的结果。第一个代码块按预期返回 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/