使用通配符的PHP正则表达式

时间:2013-03-06 14:01:34

标签: php regex regex-lookarounds

我在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'和零个或多个字符后跟']'。是什么赋予了?为什么这是正确的模式?

感谢。

3 个答案:

答案 0 :(得分:0)

PHP不支持可变长度后视,因此模式的这部分无效:

(?<!\[caption.*\])

应该警告你这件事。

此外,.*始终匹配可能的金额。因此,您的模式可能会导致匹配多个标记重叠。相反,请使用[^>](匹配任何不是右括号的内容),因为右括号不应出现在img标记内。

要解决后视问题,为什么不直接检查结束标记?这应该足够了(假设标题标签仅以与您所示的方式类似的方式使用)。

$pattern = '|(<a[^>]*><img[^>]*></a>)(?!\[/caption\])|';

匹配包含/的模式时,请使用另一个字符作为模式分隔符,以避免倾斜牙签综合征。您可以在模式周围使用几乎任何非字母数字字符。

更新:以前的正则表达式基于您提供的示例正则表达式,而不是示例数据。如果要匹配不包含图像的链接,请执行以下操作:

$pattern = '|(<a[^>]*>[^<]*</a>)(?!\[/caption\])|';

请注意,这不允许链接中间的任何标记。如果您允许标记(例如使用.*?),则正则表达式可以匹配从[caption]开始到其他地方结束的内容。

答案 1 :(得分:0)

我不知道你的正则表达式如何匹配任何一个字符串,因为你正在寻找<a.*><img.*><\/a>,而且两个锚点都不包含<img...标记。此外,寻找和禁止caption位的两个子表达式看起来很奇怪。最后,您需要确保您的代码匹配位不会贪婪,即不要使用.*[^>]*

你的意思是这样吗?

$pattern = '/(<a[^>]*>(<img[^>]*>)?<\/a>)(?!\[\/caption\])/'

regex101上进行测试。

修改:根据dan1111的建议和更新的regex101链接删除了无用的前瞻。

答案 2 :(得分:-1)

Lookbehind不允许非固定长度模式,即(*,+,?),我认为这个/<a.*><\/a>(?!\[\/caption\])/足以满足您的要求