首页 > 解决方案 > 如何修复我的正则表达式,以便参数 3 保留在捕获组 3 中?

问题描述

我有以下正则表达式:

^(\d*)(?:\.)(\d*)(?:|(?:\.)(\d*))(?:|(?:\.)([a-zA-Z0-9_-]*))?$

你可以在这里测试它。
我想用它来将版本号解析成组,例如(其中 g1 是组号 1 等等):

1.2              =>  g1(1),g2(2)    
1.2.3            =>  g1(1),g2(2),g3(3)    
1.2.3.4_or_text  =>  g1(1),g2(2),g3(3),g4(4_or_text)  

这几乎可以工作,除非第三组是可选的,如果版本有 3 个部分,则跳到第四组。
所以实际发生的是这样的:

1.2              =>  g1(1),g2(2)    
1.2.3            =>  g1(1),g2(2),g3(),g4(3)           <-- I want to fix this
1.2.3.4_or_text  =>  g1(1),g2(2),g3(3),g4(4_or_text) 

我无法确定我做错了什么。

它现在的工作方式也意味着以下内容是有效的: 1.2.3_or_text因为它被解析为g1(1),g2(2),g3(),g4(3_or_text)

标签: javaregexregex-group

解决方案


您可以将此正则表达式与 2 个可选的非捕获组一起使用:

^(\d+)\.(\d+)(?:\.(\d+)(?:\.([\w-]+))?)?$

正则表达式演示

细节:

  • ^`: 开始
  • (\d+): 在捕获组 #1 中匹配并捕获 1+ 个数字
  • \.: 匹配文字.
  • (\d+): 在捕获组 #2 中匹配并捕获 1+ 个数字
  • (?:启动非捕获组 #1
    • \.: 匹配文字.
    • (\d+): 在捕获组 #3 中匹配并捕获 1+ 个数字
    • (?:: 启动非捕获组#2
      • \.: 匹配文字.
      • ([\w-]+): 在捕获组 #4 中匹配并捕获 1+ 个单词或连字符字符
    • )?:结束非捕获组#2(可选)
  • )?:结束非捕获组#1(可选)
  • $: 结尾

推荐阅读