簡體   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