【问题标题】:Convert given relative urls to absolute urls将给定的相对 url 转换为绝对 url
【发布时间】:2019-08-01 13:34:21
【问题描述】:

我需要将给定 html 文本中的几个给定相对 url 转换为绝对 url。

html 文本将与相对和绝对 url 混合,我需要结果 html 文本,它应该只包含具有以下规则的绝对 url。

  1. 原始 html 文本包含相对 URL 和绝对 URL 的混合
  2. 需要将/test/1.html转换成https://www.example.com/test/1.html
  3. 它应该忽略具有绝对 URL(.com 和 .de)的实例,例如 http://www.example.com/test/xxx.html,https://www.example.com/test/xxx.html,https://www.example.de/test/xxx.html,http://www.example.de/test/xxx.html

我知道使用preg_replace 的最佳方法是使用PHP,并尝试了以下代码。

$server_url = "https://www.example.com";
$html = preg_replace('@(?<!https://www\.example\.com)(?<!http://www\.example\.com)(?<!https://www\.example\.de)(?<!http://www\.example\.de)/test@iU', $server_url.'/test', $html);

但是,这并没有给出预期的结果,而是转换了所有 /test 链接,包括现有的绝对 URL。所以基本上有些网址最终会变成http://www.example.dehttp://www.example.com/test/xxx.html

我不擅长regex,请帮我找到合适的regex 以获得想要的结果。

【问题讨论】:

  • 是否所有的相关网址都以/ 开头?或者它们也可以是 test/1.html 并且它们可以有查询字符串参数吗?
  • 为什么不能只检查 URL 是否以 http 开头,如果不是,则与 https://www.example.com 连接?
  • @Thefourthbird 它以/开头

标签: php regex preg-replace


【解决方案1】:

如果所有网址都以正斜杠开头,您可以使用:

(?<!\S)(?:/[^/\s]+)+/\S+\.html\S*

说明

  • (?&lt;!\S) 断言左边的不是非空白字符
  • (?:/[^/\s]+)+ 重复 1+ 次匹配 /,然后不是 / 或使用 negated character class 的空白字符
  • /\S+ 匹配 / 和 1+ 次非空白字符
  • \.html\S* 匹配示例数据中的 .html 和 0+ 次非空白字符

Regex demo

如果您还想匹配/1.html,您可以使用将量词更改为)* 而不是)+

要匹配比.html 更多的扩展名,您可以指定允许匹配的内容,例如\.(?:html|jpg|png),或者使用字符类\.[\w-()] 并添加允许匹配的内容。

【讨论】:

  • 如果它不包含html材料,例如jpg,png等怎么办
  • @JanithChinthana 然后你可以指定你想要匹配的内容使用替换 (?:png|jpg) 或使用 \w+ 匹配 1+ 字字符或使用 \S+ 匹配非空白字符(但有点宽泛)见regex101.com/r/GQoBsM/2regex101.com/r/GQoBsM/3
  • 请原谅我如此倾倒。这些链接位于大 html 文本的中间会发生什么。它似乎没有检测到。
  • 你能举个例子吗?
  • 比如说&lt;img src="/test/uploads/sample.jpg" /&gt;
【解决方案2】:

这应该匹配 root-相对网址:

^(\/[^\/]{1}.*\.html)$

您想要的网址将在$1中提供

https://regex101.com/r/E1evez/2


<?php
$urls = [
    '/test/1.html',
    'http://www.example.com/test/xxx.html',
    'https://www.example.de/test/xxx.html',
    '/relative/path/file.html'
];

foreach( $urls as $url )
{
    if( preg_match( '/^(\/[^\/]{1}.*\.html)$/', $url ) )
    {
        echo 'match: '.$url.PHP_EOL;
    }
    else
    {
        echo 'no match: '.$url.PHP_EOL;
    }
}

输出:

match: /test/1.html
no match: http://www.example.com/test/xxx.html
no match: https://www.example.de/test/xxx.html
match: /relative/path/file.html

【讨论】:

    猜你喜欢
    • 2014-12-12
    • 2021-07-28
    • 2011-10-24
    • 2019-05-10
    • 2015-06-28
    • 2011-01-01
    • 1970-01-01
    • 2011-08-04
    相关资源
    最近更新 更多