首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将字符串末尾的可选组与regex匹配?

如何将字符串末尾的可选组与regex匹配?
EN

Stack Overflow用户
提问于 2019-10-01 18:25:18
回答 2查看 511关注 0票数 2

我的琴弦如下所示:

代码语言:javascript
复制
(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):

代码语言:javascript
复制
(\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)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-01 18:38:01

如果您希望保持两个捕获组,并且希望匹配范围为1-24,然后是hour,并且可以选择一个空间和30分钟,则可以将模式缩短为:

代码语言:javascript
复制
(\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分钟

代码语言:javascript
复制
- `)` Close group 2

  • )?关闭捕获组并使其成为可选的

Regex演示

票数 2
EN

Stack Overflow用户

发布于 2019-10-01 19:10:54

我没有改变你的pattern很多,因为你没有解释你想要准确提取什么。

当您使第二组可选时,所有东西都将由.*使用,因为它是贪婪的,所以您需要修复第一个.*?

现在,第二个组也应该放在一个non capturing group中,以便将文本以类似于for 1 hour或行\n的结尾匹配。

检查一下这个:

代码语言:javascript
复制
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))

产出:

代码语言:javascript
复制
  [('1234', '1 hour'), ('4567', ''), ('1234', '1 hour 30 minutes')]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58190362

复制
相关文章

相似问题

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