2

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

谢谢。

4

3 回答 3

0

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

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

它应该警告你这一点。

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

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

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

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

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

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

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

于 2013-03-06T14:16:26.060 回答
0

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

你的意思是这样的吗?

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

在regex101上测试它。

编辑:根据 dan1111 的建议删除了无用的前瞻并更新了 regex101 链接。

于 2013-03-06T14:23:18.780 回答
-1

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

于 2013-03-06T14:21:57.763 回答