如何修复我的正则表达式,使参数3保留在捕获组3中?

时间:2019-05-21 11:42:38

标签: java regex regex-group

我有以下正则表达式:

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

您可以here对其进行测试。
我想用它来将版本号解析成组,例如(其中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)

2 个答案:

答案 0 :(得分:2)

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

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

RegEx Demo

详细信息:

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

答案 1 :(得分:2)

您的正则表达式中有多余的alternation(|)表达式

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

它告诉匹配始终通过的没有。结果,交替的第二部分永远不会匹配。

进一步的解释:替代语法类似于

(?:a|b|c)

在您的情况下,a一无是处,这就是它始终为真且匹配的原因

正确的解决方案:您还缺少可选组,并且假设应该至少包含一个数字或字母,this应该是正确的正则表达式

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

Bit of clean Solution

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

正则表达式细分

^ #Start of string
 (\d+)[.] #Match digit and dot
 (\d+) #Match next group

 (?: #Non-capturing group
   [.](\d+) #Match dot and digit
   (?:[.]([\w-]+))? #Match dot and digit. This is optional
 )? #Third and Fourth match can be optional

$ #End of string