[英]Regex - match an optionally repeated pattern of capture groups
很抱歉不知道該如何表達這個問題。 可能還有更好的標題。 我願意接受建議。
我有以下主題:
(Field1 = 'Value1') and (Field2 = 'Value2')
和
(Field1 = 'Value1') and (Field2 = 'Value2') or (Field3 = 'Value3')
我想以這樣一種方式進行匹配,即我在組中的 () 和組中的每個連詞之間都有每件事。 所以,對於第二個,一些變化
0: Field1 = 'Value1'
1: and
2: Field2 = 'Value2'
3: or
4: Field3 = 'Value3'
好消息是,我有一個適用於第一個的正則表達式:
\(([A-Za-z0-9\s\'=]+)\) (and|or) \(([A-Za-z0-9\s\'=]+)\)
https://regex101.com/r/hMXAXS/1
但是(在第二個主題上)它與第三個“和()”不匹配。 我需要支持任意數量的組。 我可以將其修改為僅查找“和 ()”,但它與第一組不匹配。
我怎樣才能告訴正則表達式這樣做? 我要么需要“重復計算”一些組(這很好),要么有一些其他方式來選擇性地查找其他模式並匹配它們。
謝謝您的幫助!
PS:我能夠讓我的應用程序使用正則表達式((and|or) \(([A-Za-z0-9\s\'=]+)\))+
然后只接受第一個group 永遠不會匹配並創建應用程序邏輯來支持它。 盡管如此,我敢打賭還有更好的方法。
您可以在此處將preg_match_all
與正則表達式模式(?<=\()(.*?)(?=\))|(?:and|or)
一起使用,如下所示:
$input = "(Field1 = 'Value1') and (Field2 = 'Value2') or (Field3 = 'Value3')";
preg_match_all("/(?<=\()(.*?)(?=\))|(?:and|or)/", $input, $matches);
print_r($matches[0]);
這打印:
Array
(
[0] => Field1 = 'Value1'
[1] => and
[2] => Field2 = 'Value2'
[3] => or
[4] => Field3 = 'Value3'
)
如果您不擔心括號表達式中可能存在定界詞或括號的邊緣情況,那么preg_split()
會生成所需的平面數組。
代碼:(演示)
$input = "(Field1 = 'Val and ue1') and (Field2 = 'Valu or e2') or (Field3 = 'Value3')";
var_export(
preg_split(
"~^\(|\)$|\) (and|or) \(~",
$input,
0,
PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE
)
);
Output:
array (
0 => 'Field1 = \'Val and ue1\'',
1 => 'and',
2 => 'Field2 = \'Valu or e2\'',
3 => 'or',
4 => 'Field3 = \'Value3\'',
)
或者通過預先修剪最外面的括號來簡化圖案。 (演示)
var_export(preg_split("~\) (and|or) \(~", trim($input, '()'), 0, PREG_SPLIT_DELIM_CAPTURE));
您還可以使用繼續元字符\G
從上一個匹配項的末尾繼續匹配:(演示)這需要88 個步驟,而 Tim 的模式需要 280 個步驟來解析字符串。
$input = "(Field1 = 'Val and ue1') and (Field2 = 'Valu or e2') or (Field3 = 'Value3')";
preg_match_all('~(?:^\(|\G(?!^)(?:\) | \())\K(?:(?:and|or)|[^)]+)~', $input, $m);
print_r($m[0]);
在提問者接受了不提供問題中所述的 output 數組結構的答案后進行編輯:(演示)
preg_match_all("~\((\S+ = '.*?')\) ?(or|and)?~", $input, $m, PREG_SET_ORDER);
print_r($m);
這不會檢查括號表達式是否出現在連詞之后。 此外,在迭代匹配時,將需要進行額外檢查以查看是否聲明了第三組 ( [2]
)。
Array
(
[0] => Array
(
[0] => (Field1 = 'Val and ue1') and
[1] => Field1 = 'Val and ue1'
[2] => and
)
[1] => Array
(
[0] => (Field2 = 'Valu or e2') or
[1] => Field2 = 'Valu or e2'
[2] => or
)
[2] => Array
(
[0] => (Field3 = 'Value3')
[1] => Field3 = 'Value3'
)
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.