正则表达式将空部分保留在同一组索引中

Regex to keep empty parts in the same group index

上下文

我有一个字符串序列,其中某些部分可以为空,也可以包含信息。我正在寻找一个正则表达式,其中每个信息总是在同一个组索引上,无论它是否为空。

预期的好处是组索引保持不变,即使组为空,所以我可以说这个或那个信息在这个或那个组中。

例子

可能的输入和预期的组输出:

1. Input: ABC_0000_0.0.0.xyz
Group 1  : ABC
Group 2  : 0000
Group 3  : 0.0.0
Group 4  : <empty>
Group 5  : <empty>

2. Input: ABC_0001_0.1.0_N.xyz
Group 1  : ABC
Group 2  : 0001
Group 3  : 0.1.0
Group 4  : _N
Group 5  : <empty>

3. Input: ABC_0002_1.1.2_foo.xyz
Group 1  : ABC
Group 2  : 0002
Group 3  : 1.1.2
Group 4  : <empty>
Group 5  : _foo

4. Input: ABC_0002_42.42.42_N_bar.xyz
Group 1  : ABC
Group 2  : 0002
Group 3  : 42.42.42
Group 4  : _N
Group 5  : _bar

我试过的

我尝试了以下正则表达式:

^(ABC)_([0-9]{4})_([0-9]+\.[0-9]+\.[0-9]+)(_[a-zA-Z]+)?(_[a-zA-Z]+)?\.xyz$

那个的问题是我只有 5 个组,例如 4。例如 1 只有 3 个组,例如 2-3 有 4 个组,但第四组可能包含两种不同类型的信息。

然后我尝试通过使用 逻辑或 来匹配空虚来调整应该捕捉第 4 组和第 5 组的部分:

^(ABC)_([0-9]{4})_([0-9]+\.[0-9]+\.[0-9]+)(|_[a-zA-Z]+)(|_[a-zA-Z]+)\.xyz$

这很有希望,它适用于所有示例,但示例 2,其中 _N 放在第 5 组,而我希望它在第 4 组.

问题

对于给定的示例,哪个正则表达式会输出相同的组?

您可以使用

^(ABC)_([0-9]{4})_([0-9]+\.[0-9]+\.[0-9]+)(?:(_[a-zA-Z]+)(|_[a-zA-Z]+))?\.xyz$

regex demo

现在,由于 (?:(_[a-zA-Z]+)(|_[a-zA-Z]+))?,第 5 组只有在第 4 组匹配后才会匹配:

  • (?: - non-capturing 组的开始:
    • (_[a-zA-Z]+) - 第 4 组:_ 和一个或多个字母
    • (|_[a-zA-Z]+) - Group 5: empty string or _` 和一个或多个字母
  • )? - non-capturing 组结束,一次或零次重复(由于 ?)。

如果第4组只能有一个字母使用

^(ABC)_([0-9]{4})_([0-9]+\.[0-9]+\.[0-9]+)(_[a-zA-Z])?(_[a-zA-Z]+)?\.xyz$

参见regex demo

现在,由于 (_[a-zA-Z])?,第 4 组只会匹配第 5 组之前 _ 之后的单个字母。