使操作符OR在正则表达式中贪婪

时间:2012-11-14 09:00:35

标签: php regex preg-match

我必须在asd["]"]

内匹配asd["]"] asd

我使用正则表达式:

/([a-z]+?(\[[^,\]]*?\]|\[\".*\"\]))/u

但它给了我asd["]

如果我改变正则表达式中OR元素的顺序:

/([a-z]+?(\[\".*\"\]|\[[^,\]]*?\]))/u

我可以获得理想的结果,但我相信这种方式其他一些情况无法奏效。这是我正则表达式的缩小版。

我怎样才能指出正则表达式来选择最长的匹配(贪婪行为)?

编辑:

使用正则表达式:

/{((\"a\")|([^b]*)})/u

我得到了

{c {"a"}

{b{c {"a"} b}

在这种情况下,regexp选择了比第一个更长的第二个OR语句。

2 个答案:

答案 0 :(得分:0)

出于某种原因,在你的两个替代方案中,你做了一个不需要它的人,并留下了一个实际上需要不合理的贪婪。要解决正则表达式的问题(虽然它会有一些注意事项),你应该在任何情况下都使用否定的字符类:

'/([a-z]+?)\[([^"\[\]]*|"[^"]*")\]/'

这应该适用于您给出的示例。它会找到最里面的asd[something here]asd["something with [][] here"]

我说的是警告。对于非引用的情况,这无法找到嵌套的事件。在asd[b efg[something]]中,它将匹配efg[something]而不是外部括号。 然而,即使可能,也会丢失内部匹配,因为匹配不能重叠。如果您希望找到最外面的有效括号(因此只有给定示例中的完整字符串),您应该查看PCRE的recursion capabilities。请注意,您必须决定最里面或最外层。 preg_matchpreg_match_all都不会找到所有嵌套匹配。

答案 1 :(得分:0)

这个正则表达式似乎对我有用:

/([a-z]+(\[[^,]*\]|\[\".*\"\]))/

在其中,我只是删除原始正则表达式的[^,\]]部分中的\],并删除了所有非贪婪的通配符,但它们似乎无论如何都没有效果。
如果你正在寻找嵌套结构,寻找“不关闭符号”永远不会找到你最长的匹配,因为它总是停在第一个(最里面的)结束角色,所以你必须选择在机箱内独特的其他东西。