繁体   English   中英

返回多个匹配但仅使用PHP和RegEX直到第一次出现模式

[英]Returning multiple matches but only till first occurrence of a pattern using PHP and RegEX

我有一个看起来像的数据集

I(0,123...789){
A(0,567...999){.......n=Marc.....}
B(2,655...265){..................}
C(3,993...333){..................}
M(8,635...254){.................;}
}
O(0,345...789){
A(0,567...999){.......n=Marc.....}
B(2,876...775){..................}
C(3,993...549){..................}
M(8,354...987){.................;}
}
I(0,987...764){
A(0,567...999){.......n=Marc.....}
B(2,543...265){..................}
C(7,998...933){..................}
M(8,645...284){.................;}
}
B(0,123...789){
.......
}
I(0,987...764){
A(0,567...999){.......n=John.....}
B(2,543...265){..................}
C(7,998...933){..................}
M(8,645...284){.................;}
}

我试图返回所有I“部分”,所以从“I”开始直到在}之后的结束标记;但仅当“I”部分包含n = Marc时。

到目前为止,我来了

^([I]\(.*\){.*n=Marc.*^[M]\(.*;}.)}

https://regex101.com/r/VSuZh5/1

但是在某些情况下,当数据具有类似的模式时

I(0,123...789){
A(0,567...999){.......n=Marc.....}
B(2,655...265){..................}
C(3,993...333){..................}
M(8,635...254){.................;}
}
O(0,345...789){
A(0,567...999){.......n=Marc.....}
B(2,876...775){..................}
C(3,993...549){..................}
M(8,354...987){.................;}
}

正则表达式返回I和O部分。 有没有办法确保它总是返回I部分?

  • 为数据集道歉,它很庞大,包含许多我无法公开的敏感数据。*

一个选项可能是匹配I ,然后匹配所有不以}开头的行并匹配至少包含n=Marc 1行

^I\([^()]*\){(?:\R(?!}|.*n=Marc).*)*\R.*\bn=Marc\b.*(?:\R(?!}).*)*\R}$

说明

  • ^字符串的开始
  • I\\([^()]*\\){匹配I跟着(...){
  • (?:非捕获组
    • \\R(?!}|.*n=Marc)匹配unicode换行序列,断言右边的内容不是}或者该行包含n = Marc
    • .*匹配任何char 0+次
  • )*关闭非捕获组并重复0次以上
  • \\R匹配unicode换行序列
  • .*\\bn=Marc\\b.*匹配任何char 0+次并在字边界之间匹配n=Marc
  • (?:非捕获组
    • \\R(?!}).*匹配换行符序列断言右边的内容不是}
  • )*关闭非捕获组并重复0次以上
  • \\R匹配换行序列
  • }比赛结束}
  • $字符串结束

正则表达式演示

如果我知道,输入总是被格式化样,宁可分成组块在一个闭合}在线的开始,跟着一个新行,如果随后通过上部: ^}\\R(?=[AZ])

然后使用preg_grep找到以I开头并包含n=Marcpreg_grep

$res = preg_grep('/^I.*n=Marc/s', preg_split('/^}\R(?=[A-Z])/m', $str));

请参阅3v4l.org上的PHP演示

在您的模式中, .*可以跳过不需要的项目,从而导致意外匹配。

我的猜测是我们想要一个表达式来返回其中包含n=MarcO部分,类似于:

(?=O\()([\s\S]*?n=Marc[\s\S]*?;}\s*})

或者可能:

(?=O\()([\s\S]*?n=Marc[\s\S]*?;})\s*}

演示1

对于I部分,我们只需将O更改为I

(?=I\()([\s\S]*?n=Marc[\s\S]*?;})\s*}

演示2

测试

$re = '/(?=I\()([\s\S]*?n=Marc[\s\S]*?;})\s*}/m';
$str = 'I(0,123...789){
A(0,567...999){.......n=Marc.....}
B(2,655...265){..................}
C(3,993...333){..................}
M(8,635...254){.................;}
}
O(0,345...789){
A(0,567...999){.......n=Marc.....}
B(2,876...775){..................}
C(3,993...549){..................}
M(8,354...987){.................;}
}
I(0,987...764){
A(0,567...999){.......n=Marc.....}
B(2,543...265){..................}
C(7,998...933){..................}
M(8,645...284){.................;}
}
B(0,123...789){
.......
}
I(0,987...764){
A(0,567...999){.......n=John.....}
B(2,543...265){..................}
C(7,998...933){..................}
M(8,645...284){.................;}
}';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

foreach ($matches as $key => $I) {
    echo $I[0] . "\n";
}

产量

I(0,123...789){
A(0,567...999){.......n=Marc.....}
B(2,655...265){..................}
C(3,993...333){..................}
M(8,635...254){.................;}
}
I(0,987...764){
A(0,567...999){.......n=Marc.....}
B(2,543...265){..................}
C(7,998...933){..................}
M(8,645...284){.................;}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM