首页 > 解决方案 > 正则表达式匹配错误的可选组

问题描述

我正在尝试匹配时间格式。时间可以写成可选的小时、分钟和毫秒。唯一需要的值是秒。因此,所有这些时间都正确写入并且应该匹配。

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 组吗?

标签: regexvb.net

解决方案


您可以将第一个可选组移动到第二个组中,以便在一个贪婪匹配组中立即连续尝试它们:

(?:(?:(\d+):)?(\d+):)?(\d+)(?:\.(\d+))?
   ^^^^^^^^^^^

查看正则表达式演示

细节

  • (?:(?:(\d+):)?(\d+):)?- 一个可选的非捕获组匹配一次或零次出现:
    • (?:(\d+):)?- 一个可选的非捕获组匹配和捕获到组 1 任何一个或多个数字,然后只是匹配:
    • (\d+)- 第 2 组:一位或多位数字
    • :- 一个冒号
  • (\d+)- 第 3 组:一位或多位数字
  • (?:\.(\d+))?- 一个可选的非捕获组匹配一个点,然后捕获到第 4 组一个或多个数字。

推荐阅读