我的琴弦如下所示:
(1) Pay for zone 1234 for 1 hour
(2) Pay for zone 4567
(3) Pay for zone 1234 for 1 hour 30 minutes以及以下正则表达式(https://regex101.com/r/MBWJUq/1):
(\d{4}).*(30 minutes|1 hour(?: 30 minutes)?|(?:[2-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?)它适用于案例(1)和(3),但不适用于案例(2)。我该怎么修呢?
它适用于case (2),如果我让最后一个组可选的话。但它没有捕捉到第一组病例(1)和(3)。
发布于 2019-10-01 18:38:01
如果您希望保持两个捕获组,并且希望匹配范围为1-24,然后是hour,并且可以选择一个空间和30分钟,则可以将模式缩短为:
(\d{4})(?:.* ((?:[1-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?))?各部分
(\d{4})捕获组1匹配4位数字(您可能会在单词边界\b前面)(?:非捕获群.*匹配任何字符0+时间后的空格(或使用.*\b)( Capture group 2 (?:[1-9]|1[0-9]|2[0-4]) hour匹配范围为1-24,然后是小时。(?: 30 minutes)?可选择匹配30分钟
- `)` Close group 2
)?关闭捕获组并使其成为可选的发布于 2019-10-01 19:10:54
我没有改变你的pattern很多,因为你没有解释你想要准确提取什么。
当您使第二组可选时,所有东西都将由.*使用,因为它是贪婪的,所以您需要修复第一个.*?。
现在,第二个组也应该放在一个non capturing group中,以便将文本以类似于for 1 hour或行\n的结尾匹配。
检查一下这个:
import re
text = """
(1) Pay for zone 1234 for 1 hour
(2) Pay for zone 4567
(3) Pay for zone 1234 for 1 hour 30 minutes
"""
RE = r'(\d{4}).*?(?:(30 minutes|1 hour(?: 30 minutes)?|(?:[2-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?)|\n)'
# same thing using compile with flags MULTILINE
# RE = re.compile(r'(\d{4}).*?(?:(30 minutes|1 hour(?: 30 minutes)?|(?:[2-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?)|$)', flags=re.MULTILINE)
print(re.findall(RE, text))产出:
[('1234', '1 hour'), ('4567', ''), ('1234', '1 hour 30 minutes')]https://stackoverflow.com/questions/58190362
复制相似问题