首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python re.search - groupdict() -日期格式匹配

Python re.search - groupdict() -日期格式匹配
EN

Stack Overflow用户
提问于 2021-10-05 13:21:14
回答 2查看 93关注 0票数 0

我需要从各种字符串中得到日期月份,比如'14 10月‘,’14 oct','14.10',‘14 10’和'14/10‘。对于这些情况,下面的代码可以正常工作。

代码语言:javascript
复制
query = '14.oct'
print(re.search(r'(?P<date>\b\d{1,2})(?:\b|st|nd|rd|th)?(?:[\s\.\-/_\\,]*)(?P<month>\d{1,2}|[a-z]{3,9})', query, re.I).groupdict())

结果:-

代码语言:javascript
复制
{'date': '14', 'month': 'oct'}

但在这种情况下(1410),它仍然捕获日期和月份。但是我不想这样,因为这将是整个字符串的另一种数字格式,而不是被视为日期和月份。结果应该是None

如何更改搜索模式?(仅适用于groupdict() )

编辑:-

以上(1410)数中提到的旁白只是为了区别于其他文本。我想说的是只有1410

下面的解决方案是我想要的,通过在regex模式中添加(?!\d{3,}\b),我从@ The -第四只鸟的答案中得到了这个想法。

谢谢

终解

代码语言:javascript
复制
import re
queries = ['14 10', '14.10', '1410', '14-10', '14/10', '14,10', '17800', '14th oct', '14thoct', '14th-oct', '14th/oct', '14-oct', '14.oct', '14oct']
max_indent = len(max(queries, key = len)) + 1

for query in queries:
    if resp := re.search(r'(?P<date>\b(?!\d{3,}\b)\d{1,2})(?:\b|st|[nr]d|th)?(?:[\s.-/_\\,-]*)(?P<month>\d{1,2}|[a-z]{3,9})', query, re.I):
        print(f"{query:{max_indent}}- {resp.groupdict()}")
    else:
        print(f"{query:{max_indent}}- 'Not a date'")

结果:-

代码语言:javascript
复制
14 10    - {'date': '14', 'month': '10'}
14.10    - {'date': '14', 'month': '10'}
1410     - 'Not a date'
14-10    - {'date': '14', 'month': '10'}
14/10    - {'date': '14', 'month': '10'}
14,10    - {'date': '14', 'month': '10'}
17800    - 'Not a date'
14th oct - {'date': '14', 'month': 'oct'}
14thoct  - {'date': '14', 'month': 'oct'}
14th-oct - {'date': '14', 'month': 'oct'}
14th/oct - {'date': '14', 'month': 'oct'}
14-oct   - {'date': '14', 'month': 'oct'}
14.oct   - {'date': '14', 'month': 'oct'}
14oct    - {'date': '14', 'month': 'oct'}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-10-05 15:05:39

不确定您不希望匹配1410 (仅以4位数字表示),也不想将(1410)与括号匹配,但要排除两者匹配,您可以确保不存在4个连续数字:

代码语言:javascript
复制
(?P<date>\b(?!\d{4}\b)\d{1,2})(?:st|[nr]d|th)?[\s./_\\,-]*(?P<month>\d{1,2}|[a-z]{3,9})

Regex演示

在括号之间不匹配任何日期

代码语言:javascript
复制
\([^()]*\)|(?P<date>\b\d{1,2})(?:st|[nr]d|th)?[\s./_\\,-]*(?P<month>\d{1,2}|[a-z]{3,9})
  • 从开口到结束圆括号的\([^()]*\)匹配
  • |
  • (?P<date>\b\d{1,2})匹配1-2位数字
  • (?:st|[nr]d|th)?可选择匹配st nd rd th
  • [\s./_\\,-]*可选择地重复匹配列表中的任何一个
  • (?P<month>\d{1,2}|[a-z]{3,9})匹配1-2位数或3-9字符a-z

Regex演示

例如

代码语言:javascript
复制
import re

pattern = r"\([^()]*\)|(?P<date>\b\d{1,2})(?:st|[nr]d|th)?(?:[\s./_\\,-]*)(?P<month>\d{1,2}|[a-z]{3,9})"
strings = ["14th oct", "14oct", "14.10", "14 10", "14/10", "1410", "(1410)"]

for s in strings:
    m = re.search(pattern, s, re.I)
    if m.group(1):
        print(m.groupdict())
    else:
        print(f"{s} --> Not valid")

输出

代码语言:javascript
复制
{'date': '14', 'month': 'oct'}
{'date': '14', 'month': 'oct'}
{'date': '14', 'month': '10'}
{'date': '14', 'month': '10'}
{'date': '14', 'month': '10'}
{'date': '14', 'month': '10'}
(1410) --> Not valid
票数 1
EN

Stack Overflow用户

发布于 2021-10-05 13:32:54

如何更改搜索模式?

您可以尝试使用负查找后断言文本(和负前瞻性断言文本),如下所示

代码语言:javascript
复制
import re
query = '14.oct'
noquery = '(1410)'
print(re.search(r'(?<!\()(?P<date>\b\d{1,2})(?:\b|st|nd|rd|th)?(?:[\s\.\-/_\\,]*)(?P<month>\d{1,2}|[a-z]{3,9})(?!\))', query, re.I).groupdict())
print(re.search(r'(?<!\()(?P<date>\b\d{1,2})(?:\b|st|nd|rd|th)?(?:[\s\.\-/_\\,]*)(?P<month>\d{1,2}|[a-z]{3,9})(?!\))', noquery, re.I))

输出

代码语言:javascript
复制
{'date': '14', 'month': 'oct'}
None

注意,它确实阻止了所有括号内的表单,即不仅是(1410),而且还有(14 10)(14/10)等等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69451272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档