非贪婪通配符 "ignored"
Non-greedy wildcard "ignored"
我遇到了以下情况:
...
preg_match('/#(.+?):(.+?)#/im','partA#partB#partC:partD#partE#partF',$matches);
...
执行后 $matches 变为
Array
(
[0] => #partB#partC:partD#
[1] => partB#partC
[2] => partD
)
如果我使用非贪婪通配符?
,$matches[1]
变成partC
不是很正常吗?我错过了什么吗?
我设法通过使用'/#([^#]+?):([^#]+?)#/im'
作为模式来解决它,但是中肯的解释将是清除云层的好方法。
谢谢。
捕获组 1 正在寻找 #
,然后是任何内容(不包括新行),直到第一个 :
。所以 partB#partC
是有道理的。
你的修改器也没有做任何事情。您没有区分大小写的字母,也没有使用锚点。
您可以在此处查看正则表达式的处理方式,https://regex101.com/r/iS0lW9/1。
当你思考正则表达式背后的基础理论时,它就有意义了。
正则表达式就是所谓的 finite state automaton (FSA)。这意味着它本质上会从左到右一次处理一个字符,偶尔会向后 "giving up" 个字符。在你的例子中,正则表达式看到第一个 #
并且注意到 #
没有参与模式的任何其他部分,开始匹配下一个标记(.+?
,在你的案件)。它会一直这样做,直到遇到冒号,然后匹配下一个标记(同样是 .+?
)。因为它是从左到右,它会匹配到第一个散列,然后停止,因为它是懒惰的。
这实际上是一个常见的误解 - 量词的 ?
修饰符不是 非贪婪的 ,它是 惰性的 .它将匹配最小可能的字符串,从左到右。
要修复您原来的正则表达式,您可以这样修改它:
/.+#(.+?):(.+?)#/im
这样做是在冒号之前的最后一个散列之前使用贪婪匹配,强制第一个捕获组只使用该散列和冒号之间的内容。同样,该组也不需要 lazy 修饰符,从而产生最终的正则表达式:
/.+#(.+):(.+?)#/im
我遇到了以下情况:
...
preg_match('/#(.+?):(.+?)#/im','partA#partB#partC:partD#partE#partF',$matches);
...
执行后 $matches 变为
Array
(
[0] => #partB#partC:partD#
[1] => partB#partC
[2] => partD
)
如果我使用非贪婪通配符?
,$matches[1]
变成partC
不是很正常吗?我错过了什么吗?
我设法通过使用'/#([^#]+?):([^#]+?)#/im'
作为模式来解决它,但是中肯的解释将是清除云层的好方法。
谢谢。
捕获组 1 正在寻找 #
,然后是任何内容(不包括新行),直到第一个 :
。所以 partB#partC
是有道理的。
你的修改器也没有做任何事情。您没有区分大小写的字母,也没有使用锚点。
您可以在此处查看正则表达式的处理方式,https://regex101.com/r/iS0lW9/1。
当你思考正则表达式背后的基础理论时,它就有意义了。
正则表达式就是所谓的 finite state automaton (FSA)。这意味着它本质上会从左到右一次处理一个字符,偶尔会向后 "giving up" 个字符。在你的例子中,正则表达式看到第一个 #
并且注意到 #
没有参与模式的任何其他部分,开始匹配下一个标记(.+?
,在你的案件)。它会一直这样做,直到遇到冒号,然后匹配下一个标记(同样是 .+?
)。因为它是从左到右,它会匹配到第一个散列,然后停止,因为它是懒惰的。
这实际上是一个常见的误解 - 量词的 ?
修饰符不是 非贪婪的 ,它是 惰性的 .它将匹配最小可能的字符串,从左到右。
要修复您原来的正则表达式,您可以这样修改它:
/.+#(.+?):(.+?)#/im
这样做是在冒号之前的最后一个散列之前使用贪婪匹配,强制第一个捕获组只使用该散列和冒号之间的内容。同样,该组也不需要 lazy 修饰符,从而产生最终的正则表达式:
/.+#(.+):(.+?)#/im