我的数据集看起来像
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部分?
答案 0 :(得分:2)
一种选择可能是匹配I
,然后匹配所有不以}
开头的行,并且至少匹配包含n=Marc
的一行
^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
匹配换行符序列}
比赛结束}
$
字符串结尾答案 1 :(得分:2)
如果我知道的话,输入总是像样本一样格式化,宁愿在行首的}
结束处分成多个块,如果后面有一个上一行:^}\R(?=[A-Z])
,则换行。
然后使用preg_grep
查找以I
开头并包含n=Marc
的项目。
$res = preg_grep('/^I.*n=Marc/s', preg_split('/^}\R(?=[A-Z])/m', $str));
在您的模式中,.*
可以跳过不需要的项目,从而导致意外的匹配。
答案 2 :(得分:0)
我的猜测是,我们希望表达式返回包含O
的{{1}}部分,类似于:
n=Marc
或者:
(?=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";
}