我需要从各种字符串中得到日期月份,比如'14 10月‘,’14 oct','14.10',‘14 10’和'14/10‘。对于这些情况,下面的代码可以正常工作。
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())结果:-
{'date': '14', 'month': 'oct'}但在这种情况下(1410),它仍然捕获日期和月份。但是我不想这样,因为这将是整个字符串的另一种数字格式,而不是被视为日期和月份。结果应该是None。
如何更改搜索模式?(仅适用于groupdict() )
编辑:-
以上(1410)数中提到的旁白只是为了区别于其他文本。我想说的是只有1410。
下面的解决方案是我想要的,通过在regex模式中添加(?!\d{3,}\b),我从@ The -第四只鸟的答案中得到了这个想法。
谢谢
终解
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'")结果:-
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'}发布于 2021-10-05 15:05:39
不确定您不希望匹配1410 (仅以4位数字表示),也不想将(1410)与括号匹配,但要排除两者匹配,您可以确保不存在4个连续数字:
(?P<date>\b(?!\d{4}\b)\d{1,2})(?:st|[nr]d|th)?[\s./_\\,-]*(?P<month>\d{1,2}|[a-z]{3,9})在括号之间不匹配任何日期
\([^()]*\)|(?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例如
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")输出
{'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发布于 2021-10-05 13:32:54
如何更改搜索模式?
您可以尝试使用负查找后断言文本(和负前瞻性断言文本),如下所示
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))输出
{'date': '14', 'month': 'oct'}
None注意,它确实阻止了所有括号内的表单,即不仅是(1410),而且还有(14 10)、(14/10)等等。
https://stackoverflow.com/questions/69451272
复制相似问题