【问题标题】:Make all absolute links relative使所有绝对链接相对
【发布时间】:2017-03-30 14:18:18
【问题描述】:

我正在为这个问题寻找一个正则表达式解决方案。如果这使事情变得更容易,它可以是一个多步骤的解决方案。重要提示:测试字符串只是一个完整 HTML DOM 的 sn-p,只有图像可以通过它来寻址,任何其他 URL 都应该单独保留。

这是一张图片:

<img 
src="https://www.example.com/de/wp-content/uploads/sites/1/2017/03/image.jpg"
data-srcset="
 https://www.example.com/de/wp-content/uploads/sites/1/2017/03/img1.jpg 507w,
 https://www.example.com/de/wp-content/uploads/sites/1/2017/03/img2.jpg 780w,
 https://www.example.com/de/wp-content/uploads/sites/74/2017/03/img3.jpg 950w"
data-sizes="
 (min-width: 80em) calc(0.5 * (100vw - (100vw- 57em))),
 (min-width: 48em) calc(0.5 * (100vw - 5em)),
 calc(100vw - 1em)"
alt="image" class="lazyload">

作为单行者:

<img src="https://www.example.com/de/wp-content/uploads/sites/1/2017/03/image.jpg" data-srcset="https://www.example.com/de/wp-content/uploads/sites/1/2017/03/img1.jpg 507w, https://www.example.com/de/wp-content/uploads/sites/1/2017/03/img2.jpg 780w, https://www.example.com/de/wp-content/uploads/sites/74/2017/03/img3.jpg 950w" data-sizes="(min-width: 80em) calc(0.5 * (100vw - (100vw- 57em))), (min-width: 48em) calc(0.5 * (100vw - 5em)), calc(100vw - 1em)" alt="image" class="lazyload">

想要的结果是需要去掉协议、域和第一个目录——也就是说:/wp-content 前面的所有内容。我这样做的语言是 php。

对于 src 部分,我有

 preg_replace("/(<img.*?src=\")(.*?)(\/wp-content.*?\")(.*>)/", '"$1$3$4"', $string);

下面的答案是正确的。 大多数 HTML 文档应该能够加载。帮自己一个忙,尽量做到有效,无论如何这是一件好事。如果您自己没有生成有问题的 HTML,请尝试在使用之前对其进行处理。

对于 data-srcset 问题,只需单独解析该参数即可。

完全比较您的 DOM 之前和之后。 @dom-&gt;saveHTML() 方法使不需要关闭的封闭标签关闭。就像&lt;meta arg="yada"/&gt; 变成&lt;meta arg="yada"&gt;(缺少关闭反斜杠)。另见Are (non-void) self-closing tags valid in HTML5?

【问题讨论】:

标签: php regex preg-replace pcre


【解决方案1】:

不要。使用解析器分析 DOM 并将正则表达式直接应用于 DOM 元素/属性。

<?php

$dom = new DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED);

$xpath = new DOMXPath($dom);
$images = $xpath->query("//img[contains(@src, 'wp-content')]");

$regex = '~^.+?(?=/wp-content/)~';
foreach($images as $img) {
    $img->setAttribute('src', 
        preg_replace($regex, 'https://anotherdomain.com', $img->getAttribute('src'))
    );
}

echo $dom->saveHTML();

已经回答了十几次为什么用正则表达式解析 HTML 不是一个好主意,最喜欢的答案之一是: RegEx match open tags except XHTML self-contained tags


但是,如果您的 HTML 无效,您可以使用以下正则表达式(在详细模式下):
(?:\G(?!\A)|<img)
(?s:.+?\bsrc=['"])\K
https?://.+?(?=/wp-content/)

working on regex101.com

【讨论】:

  • 不要?请详细说明。
  • “几十次” ...对于普通读者或那些提出正确问题的人 ;-) 如果我偶然发现了这个 ... 有趣的答案 ;-) ...
  • @wloske:确实如此:)
  • 哦,我有没有提到你的例子不起作用 :-) 基本上是因为我的 HTML 无效,我也不能保证。
  • @wloske:然后在底部查看更新的答案。当然,虽然不建议使用正则表达式来分析 HTML 字符串是可能的。
猜你喜欢
  • 1970-01-01
  • 2012-02-26
  • 2010-09-25
  • 2012-04-02
  • 2021-02-06
  • 2015-02-22
  • 2010-10-07
  • 2015-12-04
  • 2015-01-13
相关资源
最近更新 更多