簡體   English   中英

正則表達式 - 匹配可選重復的捕獲組模式

[英]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'
        )
)

如果您同意每場比賽獲得三個小組......

1 = 鍵 2 = 值 3 = 連詞

那么這個正則表達式也將允許在值中使用括號。

/\((.*?) = '(.*?)'\) ?(and|or)?/gm

這會導致此字符串的這些匹配...

(Field1 = 'Value1') and (Field2 = '(in parenthesis)') and (Field3 = 'Value3')

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM