我在PHP中有两个字符串:
$string = '<a href="http://localhost/image1.jpeg" /></a>';和
$string2 = '[caption id="attachment_5" align="alignnone" width="483"]<a href="http://localhost/image1.jpeg" /></a>[/caption]';我正在尝试匹配第一种类型的字符串。这是没有被“caption ...”括起来的字符串。和'/caption‘。到目前为止,我想使用这样的东西:
$pattern = '/(?<!\[caption.*\])(?!\[\/caption\])(<a.*><img.*><\/a>)/';但是PHP也用这个模式匹配第一个字符串,即使它前面没有'caption‘和零个或多个字符后跟'’。怎么回事?为什么会这样?正确的模式是什么?
谢谢。
发布于 2013-03-06 22:16:26
PHP不支持可变长度的后视,所以模式的这一部分是无效的:
(?<!\[caption.*\])它应该警告你这一点。
此外,.*始终匹配最大的可能数量。因此,您的模式可能会导致与多个标签重叠的匹配。相反,应该使用[^>] (匹配不是右方括号的任何内容),因为右方括号不应该出现在img标记内。
为了解决后顾之忧,为什么不只检查结束标记呢?这应该足够了(假设仅以类似于您所显示的方式使用标题标签)。
$pattern = '|(<a[^>]*><img[^>]*></a>)(?!\[/caption\])|';当匹配包含/__的模式时,请使用另一个字符作为模式分隔符,以避免倾斜牙签综合征。您几乎可以在模式周围使用任何非字母数字字符。
更新:之前的正则表达式基于您给出的示例正则表达式,而不是示例数据。如果要匹配不包含图像的链接,请执行以下操作:
$pattern = '|(<a[^>]*>[^<]*</a>)(?!\[/caption\])|';请注意,这不允许在链接中间有任何标记。如果允许使用标记(比如使用.*?),正则表达式可以匹配从[caption]开始到其他地方结束的内容。
发布于 2013-03-06 22:23:19
我不明白您的正则表达式如何匹配这两个字符串,因为您正在寻找<a.*><img.*><\/a>,而两个锚点都不包含<img...标记。此外,在我看来,寻找和禁止caption-bits的两个子表达式的位置也很奇怪。最后,您需要确保您的标记匹配位不会表现得贪婪,即不要使用.*而要使用[^>]*。
你是说像这样的东西吗?
$pattern = '/(<a[^>]*>(<img[^>]*>)?<\/a>)(?!\[\/caption\])/'在regex101上测试它。
编辑:根据dan1111的建议,删除了无用的前视,并更新了regex101链接。
发布于 2013-03-06 22:21:58
Lookbehind不允许非固定长度的模式,即(*,+,?),我认为这个/<a.*><\/a>(?!\[\/caption\])/足以满足您的要求
https://stackoverflow.com/questions/15249322
复制相似问题