Regex两个独立的嵌套捕获组



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

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来容纳所有不包含在括号中的整数。然后,一个名为QTYS的组来保存括号中包含的所有整数。

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

是否可以将LINE_NUMBERS设为[1,2,3,4](数组或某种字符串(然后CCD_ 8变为CCD_ 9注意:我仍然想捕获括号。

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

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

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

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

您可以在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锚点为给定的示例数据获取两个单独的组,但它将使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组,并匹配字符类中列出的单个字符和可选的whitspace字符
  • (?<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演示| PHP演示

最新更新