[英]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.