【问题标题】:PHP regex, skip <link> tags when rel="canonical"PHP 正则表达式,当 rel="canonical" 时跳过 <link> 标签
【发布时间】:2017-03-28 09:53:45
【问题描述】:

我在 WordPress 中运行一个 PHP 脚本,使用以下正则表达式从所有链接中删除 http:https: 协议:

$links = preg_replace( '/<input\b[^<]*\bvalue=[\"\']https?:\/\/(*SKIP)(*F)|https?:\/\//', '//', $links );

对于第一部分:&lt;input\b[^&lt;]*\bvalue=[\"\']https?:\/\/(*SKIP)(*F),这将跳过任何具有 http: / https: 值的 &lt;input&gt; 标签,例如:

<input type="url" value="http://example.com">

另外,我希望它跳过任何具有rel="canonical" 属性的&lt;link&gt; 标签:

<link rel="canonical" href="http://example.com/remove-http/" />

使用regex tester,我一直在尝试更新逻辑。到目前为止,这是我想出的:

<(input|link)\b[^<]*\(value|rel)=[\"\'](https?:\/\/|canonical)(*SKIP)(*F)|https?:\/\/

但这对我不起作用。

【问题讨论】:

标签: php regex


【解决方案1】:

(*SKIP)(*F) 动词用于丢弃到目前为止匹配的文本,并在将文本与这些动词之前的模式匹配后,从正则表达式索引所在的位置开始搜索下一个匹配项。

所以,要匹配word1 word2,放下它们并继续寻找word3,你需要使用

'~(?:word1|word2)(*SKIP)(*F)|word3~'

(?:...) 非捕获组将对必须删除的备选方案进行分组。

在您的情况下,应该匹配整个 &lt;link...&gt;,而不仅仅是属性。因此,在上述正则表达式中,您需要 link\b[^&gt;]*?\brel=[\'\"]canonical[\'\"][^&gt;]*&gt; 而不是 word2

但是,您应该考虑使用与您的环境兼容的 HTML 解析器(我看到您的说明,那里的 DOMDocument 出现故障)。

【讨论】:

  • 你说得对,我切换到DOMDocument,但它引起了问题。
【解决方案2】:

您应该考虑使用内置的 PHP DOM 类。

http://php.net/manual/en/book.dom.php

HTML 是一种非常丰富的语言,而正则表达式不足以有效地解析它。请永远不要使用正则表达式解析 HTML。

使用正则表达式解析 HTML 会让 SO 用户发疯:https://stackoverflow.com/a/1732454/5909136

【讨论】:

  • 我在其他人的帮助下完成了 SO,see this previous committhis question。但它引起了更多问题,尤其是在 WordPress 的管理面板中。在我恢复到正则表达式之前,非常欢迎您帮助改进该版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多