正则表达式两个独立的嵌套捕获组

Regex two separate nested capturing groups

我有一个正则表达式和测试用例

https://regex101.com/r/5Z5Lop/1

^(?<KEY>CONF|ESD|TRACKING)[:;'\s]\s*(?<DATA>.*?)\s*(?:L[:;'\s]\s*\K(?<LINE_DATA>.*?))?(?<INITIALS>\*[a-zA-Z]+)?\s*$

查看 LINE_DATA 命名组。

是否可以将该组分成两个独立的组?

我想要一组 LINE_NUMBERS 来保存括号中未包含的所有整数。 然后,1 组称为 QTYS 来保存括号中包含的所有整数。

所以目前 LINE_NUMBERS 产量 "1,2,3(4),5(12) "

是否可以让 LINE_NUMBERS 成为 [1,2,3,4](数组或某种字符串) 然后 QTYS 成为 [(4),(12)] 注意:我仍然想捕获括号。

如果可能的话,我想在当前的正则表达式中执行此操作,并且不会使我目前拥有的内容过于复杂。

现在,我正在通过 post 使用单独的正则表达式进行处理来获取这些数据。我正在使用 php

preg_match_all('/\d+(?!\s*\))/i', $ret_data['LINE_DATA'], $ret_data['LINE_NUMBERS']);

谢谢! preg_match_all('/\(\s*\d\s*\)/i', $ret_data['LINE_DATA'], $ret_data['QUANTITIES']);

您可以在 post-processing 中为 QUANTITIES 使用单一模式,在 LINE_NUMBERS 中使用交替 | 并从结果中删除空条目。

$re = '/^(?<KEY>CONF|ESD|TRACKING)[:;\'\s]\s*(?<DATA>.*?)\s*(?:L[:;\'\s]\s*\K(?<LINE_DATA>.*?))?(?<INITIALS>\*[a-zA-Z]+)?\s*$/i';
$str = 'esd:      here is my data      L:       1,2,3(4),5(12)   *sm          ';
preg_match($re, $str, $matches);

preg_match_all('/(?<QUANTITIES>\(\d+\))|(?<LINE_NUMBERS>\d+)/', $matches["LINE_DATA"], $numbers);

print_r(array_filter($numbers["QUANTITIES"]));
print_r(array_filter($numbers["LINE_NUMBERS"]));

输出

Array
(
    [3] => (4)
    [5] => (12)
)
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [4] => 5
)

可以选择使用 \G 锚点为给定的示例数据获取 2 个单独的组,但它会使后面的 INITIALS 部分成为可选的:

^(?<KEY>CONF|ESD|TRACKING)[:;'\s]\s*(?<DATA>.*?)\s*L[:;'\s]\s*|\G(?!^)(?:(?<QUANTITIES>\(\d+\))|(?<LINE_NUMBERS>\d+)),?(?:\s*(?<INITIALS>\*[a-zA-Z]+)\s*$)?
  • ^ 字符串开头
  • (?<KEY>CONF|ESD|TRACKING)[:;'\s]\s* 带替代项的 KEY 组,并匹配字符 class 中列出的单个字符和可选的空白字符
  • (?<DATA>.*?)\s* 匹配 DATA 组,任何非贪婪的字符后跟可选的空白字符
  • L[:;'\s]\s* 匹配 L 任何列表字符和可选的空白字符
  • |
  • \G(?!^) 断言上一场比赛结束时的位置,而不是开始
  • (?:非捕获组
    • (?<QUANTITIES>\(\d+\)) 分组数量,匹配括号之间的 1+ 位数字
    • |
    • (?<LINE_NUMBERS>\d+)组LINE_NUMBERS,匹配1+位数字
  • )关闭非捕获组
  • ,? 匹配一个可选的逗号
  • (?:\s*(?<INITIALS>\*[a-zA-Z]+)\s*$)? 带有组 INITIALS 的可选非捕获组

Regex demo | PHP demo