regex 正则表达式捕获可选组

mkshixfv  于 2022-11-26  发布在  其他
关注(0)|答案(3)|浏览(206)

我尝试捕获2组数字,每组都是可选的,只有包含数字时才能捕获。下面是它应该匹配的所有有效组合的列表:

  1. 123(456)
  2. 123
  3. (456)
  4. abc(456)
  5. 123(efg)
    这些组合无效,不应匹配:
  6. abc(efg)
  7. abc
  8. (efg)
    然而,我的正则表达式在#4#5组合上失败,即使它们包含数字。
    第一个
    因此,问题是为什么在一个组后面使用?时,如果没有匹配项,它不会“跳过”该组?
    P.S.使用此正则表达式时,它还捕获#4,但不捕获#5/(?:^|(\d+)?)(?:\((\d+)\))?$/
az31mfrm

az31mfrm1#

您可以使用lookahead来解决您所寻找的问题,请参阅:

(?=^\d+(?:\(|$))(\d+)|(?=\d+\)$)(\d+)

粗略翻译:从开头开始以括号结尾的数字(或行尾),或文本中某处括号中的数字

回答有关可选捕获组的问题

是的,如果一个组被标记为可选,例如(A*)?,它会使整个组都是可选的。在您的情况下,这只是正则表达式不匹配的情况-即使可选部分不存在(在正则表达式调试器的帮助下验证)

6ojccjat

6ojccjat2#

@ WiktorStribiew和@akash有很好的想法,但它们基于全局标志,这需要额外的循环来收集所有匹配。
现在,我提出了这个正则表达式,它匹配任何东西,但它只捕获我需要的东西。
第一个

sh7euo9m

sh7euo9m3#

这里有一个没有全局标志的想法,假设只匹配所需的项:

^(?=\D*\d)(\d+)?\D*(?:\((\d*)\))?\D*$
  • ^(?=\D*\d)^start处的lookahead检查是否至少有一个digit
  • (\d+)?capturing将数字移到optional * 第一组 *
  • \D*后跟任意数量的 * 非数字 *
  • (?:\((\d*)\))?括号中的数字为可选 * 第二组 *
  • \D*$匹配\D * 非数字 * 的任意数量,最多可达$结尾

查看JS演示或demo at regex101[^\d\n]仅用于多行演示)

相关问题