[英]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=Marc
的preg_grep
。
$res = preg_grep('/^I.*n=Marc/s', preg_split('/^}\R(?=[A-Z])/m', $str));
在您的模式中, .*
可以跳过不需要的项目,从而导致意外匹配。
我的猜测是我们想要一个表达式来返回其中包含n=Marc
的O
部分,类似于:
(?=O\()([\s\S]*?n=Marc[\s\S]*?;}\s*})
或者可能:
(?=O\()([\s\S]*?n=Marc[\s\S]*?;})\s*}
对于I
部分,我们只需将O
更改为I
:
(?=I\()([\s\S]*?n=Marc[\s\S]*?;})\s*}
$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.