如何捕获重复捕获组中每个组的组号

南特

我的正则表达式就是这样**(A)(([+-]\d{1,2}[YMD])*)**,它可以像预期的那样匹配A + 3M,A-3Y + 5M + 3D等。

但是我想捕获此子模式的所有组。**([+-]\d{1,2}[YMD])***对于下面的示例A-3M + 2D,我只能看到4个组。A-3M+2D (group 0), A(group 1), -3M+2D (group 2), +2D (group 3)

有没有办法让我**-3M**成为一个独立的小组?

维克多·史翠比维

重复的捕获组通常仅捕获最后一次迭代Kotlin和Java均是如此,因为这些语言没有任何方法可以跟踪每个捕获组堆栈。

您可以采取的解决方法是,首先根据字符串应匹配的特定模式验证整个字符串,然后将字符串提取或拆分为多个部分。

对于当前方案,您可以使用

val text = "A-3M+2D" 
if (text.matches("""A(?:[+-]\d{1,2}[YMD])*""".toRegex())) {
  val results =  text.split("(?=[-+])".toRegex())
  println(results)
}
// => [A, -3M, +2D]

观看Kotlin演示

这里,

  • text.matches("""A(?:[+-]\d{1,2}[YMD])*""".toRegex())确保整个字符串匹配A,然后0或多次出现的+-,1或2位数字用YMD
  • .split("(?=[-+])".toRegex())-之前使用空字符串分割文本+

图案细节

  • ^-隐式输入.matches()-字符串开头
  • A-A子串
  • (?:-一个非捕获组的开始
    • [+-]-一个字符类匹配+-
    • \d{1,2} -一到两位数字
    • [YMD]-字符类匹配YMD
  • )*-非捕获组的结尾,重复0次或更多次(由于*量词)
  • \z-隐式输入matches()-字符串末尾。

分割时,我们只需要查找-之前的位置+,因此我们使用正向前行(?=[-+])该位置与紧跟在+之后的位置相匹配-这是一种非消耗模式,+-匹配不添加到匹配值中。

单个正则表达式的另一种方法

您也可以使用\G基于正则表达式的方法,首先在字符串的开头检查字符串格式,如果成功,则仅开始匹配连续的子字符串:

val regex = """(?:\G(?!^)[+-]|^(?=A(?:[+-]\d{1,2}[YMD])*$))[^-+]+""".toRegex()
println(regex.findAll("A-3M+2D").map{it.value}.toList())
// => [A, -3M, +2D]

参见另一个Kotlin演示regex演示

细节

  • (?:\G(?!^)[+-]|^(?=A(?:[+-]\d{1,2}[YMD])*$))-先前成功匹配的结尾,然后是字符串的+-(请参阅\G(?!^)[+-])或(|A,然后是+/ -然后是0或多次出现的/ ,1或2位数字,然后是YMD直到字符串的结尾(请参阅^(?=A(?:[+-]\d{1,2}[YMD])*$)
  • [^-+]+- 1个以上字符比其他-+我们在这里不必太小心,因为在字符串开始时先行进行了繁重的工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章