regex - 正则表达式匹配错误的可选组
问题描述
我正在尝试匹配时间格式。时间可以写成可选的小时、分钟和毫秒。唯一需要的值是秒。因此,所有这些时间都正确写入并且应该匹配。
10:11:12.123 '10 hours, 11 minutes, 12 seconds and 123 milliseconds
10:11:12 '10 hours, 11 minutes and 12 seconds
11:12.123 '11 minutes, 12 seconds and 123 milliseconds
11:12 '11 minutes and 12 seconds
12.123 '12 seconds and 123 milliseconds
12 '12 seconds
我的正则表达式如下所示:(?:(?:(\d*):)?(?:(\d*):)?(\d*)(?:\.(\d*))?)
我希望每个组都对应正确的值。所以第 1 组应该总是返回小时,第 2 组应该总是返回分钟,等等......我在Regex101中尝试过这个,但正如你在这些结果中看到的那样,当没有小时数时,第 1 组总是比第 2 组更受欢迎。它与时间11:12
完美匹配,但它11
位于第 1 组,告诉我它是小时,而实际上是分钟。这并不奇怪,因为这个字符串中的分钟与第 1 组匹配。但这不是我想要的。
如何确保每个组始终对应正确的时间部分?我可以以某种方式将第 2 组优先于第 1 组吗?
解决方案
您可以将第一个可选组移动到第二个组中,以便在一个贪婪匹配组中立即连续尝试它们:
(?:(?:(\d+):)?(\d+):)?(\d+)(?:\.(\d+))?
^^^^^^^^^^^
查看正则表达式演示
细节
(?:(?:(\d+):)?(\d+):)?
- 一个可选的非捕获组匹配一次或零次出现:(?:(\d+):)?
- 一个可选的非捕获组匹配和捕获到组 1 任何一个或多个数字,然后只是匹配:
(\d+)
- 第 2 组:一位或多位数字:
- 一个冒号
(\d+)
- 第 3 组:一位或多位数字(?:\.(\d+))?
- 一个可选的非捕获组匹配一个点,然后捕获到第 4 组一个或多个数字。
推荐阅读
- json - Golang JSON 序列化/反序列化
- laravel - Laravel - 不允许序列化“闭包”
- mysql - 生成表示组内行索引的列
- docker - Docker:Alpine Linux:为什么要添加 apk
在容器中持久化? - wheelnav.js - 如何在 wheelnav.js 中缩放 SVG 的图标大小?
- clojure - “lein ring uberwar”将 NPE 扔进了资产缩小器
- c# - 是否可以使用不同的变量类型设置类变量
- stm32 - NuttX:如何为 STM32F7 板添加 PWM 支持?(stm32_pwm.h 未找到)
- azure - 在构建管道中在 Azure DevOps 上运行分布式 JMeter 测试
- python - 使用 def 函数重新运行 Python 程序