将相对URL转换为绝对URL

4
例如,我有一个像这样的字符串:
$html = '
            <a href="test.html">test</a>
            <a href="http://mydomain.com/test.html">test</a>
            <a href="http://otherdomain.com/test.html">test</a>
            <a href="someothertest/otherdir/hi.html">hi</a>
        ';

我希望你能为没有给出绝对域的所有href添加绝对URL。
$html = '
            <a href="http://mydomain.com/test.html">test</a>
            <a href="http://mydomain.com/test.html">test</a>
            <a href="http://otherdomain.com/test.html">test</a>
            <a href="http://mydomain.com/someothertest/otherdir/hi.html">hi</a>
        ';  

最好的方法是什么?我想可能与正则表达式有关,但我的正则表达式技巧不太行 ;)

提前感谢!


虽然正则表达式可能暂时能够帮助你,但在以后的某个时间点上它可能会变得危险。最好将其解析为XML,检查属性是否以“http://”开头,如果不是,则在前面添加“http://mydomain.com/”。 - Amarghosh
应该将<a href="../test.html">test</a>添加到示例中... - Hinek
3个回答

8

找到了一个好方法:

$html = preg_replace("#(<\s*a\s+[^>]*href\s*=\s*[\"'])(?!http)([^\"'>]+)([\"'>]+)#", '$1http://mydomain.com/$2$3', $html);

如果你的 $html 中还有邮件链接,你可以使用 (?!http|mailto)

来进行筛选。


4
$domain = 'http://mydomain';
preg_match_all('/href\="(.*?)"/im', $html, $matches);
foreach($matches[1] as $n=>$link) {
    if(substr($link, 0, 4) != 'http')
        $html = str_replace($matches[1][$n], $domain . $matches[1][$n], $html);
}   

5
Romka,我替你格式化了代码,这样我们阅读的时候就不会眼花了。 - John Conde

1
前一个答案会导致您的第一个和第四个示例出现问题,因为它未包括正斜杠以分隔页面和页面名称。不可否认,这可以通过将其附加到 $domain 来简单地修复,但如果这样做,href="/something.php" 将最终变成两个.
只是为了提供替代的正则表达式解决方案,您可以尝试以下内容...
$pattern = '#'#(?<=href=")(.+?)(?=")#'';
$output = preg_replace_callback($pattern, 'make_absolute', $input);

function make_absolute($link) {
    $domain = 'http://domain.com';
    if(strpos($link[1], 'http')!==0) {
        if(strpos($link[1], '/')!==0) {
            return $domain.'/'.$link[1];
        } else {
            return $domain.$link[1];
        }
    }
    return $link[1];
}

然而值得注意的是,使用类似href="example.html"这样的链接时,链接是相对于当前目录的,到目前为止展示的两种方法都不能正确处理不在根目录中的相对链接。为了提供一个更好的解决方案,需要更多有关信息来源的详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接