在一个Python正则表达式中匹配两个模式,仅捕获非空值

4 投票
2 回答
3627 浏览
提问于 2025-04-17 08:17

经过一番搜索和阅读,我不太确定我想做的事情是否能一步完成。我想要的结果是能够匹配以下内容:

(\d{1,4})/(\d{1,2})/(\d{1,2})

2011/12/13

或者这个

(\d{1,2})/(\d{1,4})/(\d{1,2})

12/2011/13

或者这个

(\d{1,2})/(\d{1,4})/(\d{1,2})

12/13/2011

并且能把括号里的值提取出来。


所以我做的是把这三个用非捕获的 语句包裹起来:

^(?:(\d{1,4})/(\d{1,2})/(\d{1,2}))|(?:(\d{1,2})/(\d{1,4})/(\d{1,2}))|(?:(\d{1,2})/(\d{1,2})/(\d{1,4}))$

唯一的问题是,如果我在这个内容上使用它:

2011/12/13

我得到的结果是:

2100
10
10
Empty
Empty
Empty
Empty
Empty
Empty

我不太喜欢这些空的捕获。有没有办法设置,只返回非空的字符串呢?

我能想到很多变通的方法来让这个工作,比如先匹配正确的模式,然后再匹配正确的捕获,或者检查捕获的值是否为空字符串,但我觉得这应该可以在正则表达式本身里实现。

任何帮助都非常感谢。

谢谢 :)

2 个回答

1

这是我尝试的一个简短而直接的版本:

(\d{2,4})(?=/)/(\d{2,4})(?=/)/(\d{2,4})$
5

这样怎么样:

^(?:(?=\d{1,4}/\d{1,2}/\d{1,2})|(?=\d{1,2}/\d{1,4}/\d{1,2})|(?=\d{1,2}/\d{1,2}/\d{1,4}))(\d+)/(\d+)/(\d+)$

这里的3个向前看(look ahead)确保你有日期的三种格式中的任意一种,然后提取出日期的三个部分。

解释:

^                              : begining of the string
(?:                            : begin non capture group
  (?=\d{1,4}/\d{1,2}/\d{1,2})  : assume the format is yyyy/mm/dd
  |                            : or
  (?=\d{1,2}/\d{1,4}/\d{1,2})  : format dd/yyyy/mm
  |                            : or
  (?=\d{1,2}/\d{1,2}/\d{1,4})  : format dd/mm/yyyy
)                              : end of non capture group
(\d+)/(\d+)/(\d+)              : capture the 3 elements
$                              : end of string

撰写回答