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

Regex 如何在重复捕获组中捕获每个组的组号,regex,kotlin,Regex,Kotlin,我的正则表达式类似于**(A)(([+-]\d{1,2}[YMD])**,与预期的A+3M、A-3Y+5M+3D等匹配 但是我想捕获这个子模式的所有组**([+-]\d{1,2}[YMD])*** 对于下面的示例A-3M+2D,我只能看到4组A-3M+2D(第0组)、A(第1组)、-3M+2D(第2组)、+2D(第3组) 有没有办法把**-3M**作为一个单独的组?通常重复捕获组。Kotlin和Java都是如此,因为这些语言没有任何方法可以跟踪每个捕获组堆栈 作为一种解决方法,您可以首先根据字符

我的正则表达式类似于
**(A)(([+-]\d{1,2}[YMD])**
,与预期的A+3M、A-3Y+5M+3D等匹配

但是我想捕获这个子模式的所有组
**([+-]\d{1,2}[YMD])***
对于下面的示例A-3M+2D,我只能看到4组<代码>A-3M+2D(第0组)、A(第1组)、-3M+2D(第2组)、+2D(第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]

这里,

  • text.matches(“'A(?:[+-]\d{1,2}[YMD])*”.toRegex())
    确保整个字符串匹配
    A
    ,然后匹配0或更多次出现的
    +
    -
    ,1或2位后跟
    Y
    M
    d
  • .split(“(?=[-+])”.toRegex()
    -
    +
    前面用空字符串拆分文本
图案细节

  • ^
    -隐式在
    .matches()中
  • A
    -一个
    A
    子字符串
  • (?:
    -开始:
    • [+-]
      -匹配的
      +
      -
    • \d{1,2}
      -一到两位数字
    • [YMD]
      -匹配
      Y
      M
      D
  • )*
    -结束非捕获组,重复0次或更多次(由于
    *
    量词)
  • \z
    -隐式在
    匹配()中
    -字符串结尾
拆分时,我们只需要在
-
+
之前找到位置,因此我们使用一个正的
(?=[-+])
,它匹配紧跟在
+
-
之后的位置。这是一种非消费模式,匹配的
+
-
不会添加到匹配值中

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

您还可以使用基于
\G
的正则表达式首先在字符串开头检查字符串格式,并且只有在检查成功时才开始匹配连续的子字符串:

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

详细信息

  • (?:\G(?)[+-]| ^(=A(?:[+-]\d{1,2}[YMD])
    -前一次成功匹配的结束,然后是
    +
    -
    (请参见
    \G(?)[+-]
    )或(
    )紧跟
    的字符串开头,然后是
    +/code>的0次或更多次出现,1或2个数字,然后
    Y
    M
    D
    直到字符串结束(请参见
    ^(?=A(?[+-]\D{1,2}[YMD])*$)
  • [^-+]+
    -1个或多个字符,而不是
    -
    +
    。我们在这里不必太小心,因为前面的人在绳子开始时起了很大的作用

这不是一个递归模式,而是一个重复捕获组的模式。你的编程语言是什么?另见更正`这是kotlinMarcin,请不要删除
kotlin
标记,这是一个与kotlin相关的问题,OP确认。根据国家规定,所有带有此标记的问题还应包括一个指定适用编程语言或工具的标记。它工作正常。谢谢你能不能在正则表达式中加上?:和拆分中加上?=的解释