正则表达式,用于用相对URL替换绝对URL

时间:2019-07-16 00:32:33

标签: php regex preg-replace

如何编写将所有绝对URL转换为相对路径的正则表达式。例如:

src="http://www.test.localhost/sites/ 

将成为

src="/sites/"

域不是静态的。

我不能使用parse_url(根据answer),因为它是一个较大的字符串的一部分,该字符串也包含无URL数据。

3 个答案:

答案 0 :(得分:0)

解决方案

您可以使用以下正则表达式:

/https?:\/{2}[^\/]+/

符合以下条件的人:

http://www.test.localhost/sites/
http://www.domain.localhost/sites/
http://domain.localhost/sites/

因此它将是:

$domain = preg_replace('/https?:\/{2}[^\/]+/', '', $domain);

说明

http: Look for 'http'
s?: Look for an 's' after the 'http' if there's one
: : Look for the ':' character
\/{2}: Look for the '//'
[^\/]+: Go for anything that is not a slash (/)

答案 1 :(得分:0)

我的猜测是,该表达式或该表达式的改进版本可能在某种程度上有效:

^\s*src=["']\s*https?:\/\/(?:[^\/]+)([^"']+?)\s*["']$

如果要浏览/简化/修改该表达式,请在this demo的右上角进行解释。


测试

$re = '/^\s*src=["\']\s*https?:\/\/(?:[^\/]+)([^"\']+?)\s*["\']$/m';
$str = 'src=" http://www.test.localhost/sites/  "
src=" https://www.test.localhost/sites/"
src=" http://test.localhost/sites/   "
  src="https://test.localhost/sites/   "
      src="https://localhost/sites/   "
src=\'https://localhost/   \'
src=\'http://www.test1.test2.test3.test4localhost/sites1/sites2/sites3/   \'';
$subst = 'src="$1"';

var_export(preg_replace($re, $subst, $str));

输出

src="/sites/"
src="/sites/"
src="/sites/"
src="/sites/"
src="/sites/"
src="/"
src="/sites1/sites2/sites3/"

RegEx电路

jex.im可视化正则表达式:

enter image description here

答案 2 :(得分:0)

$dom = new DOMDocument;
$dom->loadHTML($yourHTML)
$xp = new DOMXPath($dom);

foreach($xp->query('//@src') as $attr) {
    $url = parse_url($attr->nodeValue);

    if ( !isset($url['scheme']) || stripos($url['scheme'], 'http']) !== 0 )
        continue;

    $src = $url['path']
         . ( isset($url['query']) ? '?' . $url['query'] : '' )
         . ( isset($url['fragment']) ? '#' . $url['fragment'] : '' );

    $attr->parentNode->setAttribute('src', $src);
}

$result = $dom->saveHTML();

我添加了if条件来跳过无法确定src属性的开头是域还是路径的开头的情况。根据您要尝试执行的操作,可以删除此测试。

如果您正在处理html文档的一部分(即不是完整的文档),则必须使用以下内容更改$result = $dom->saveHTML()

$result = '';
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $childNode) {
    $result . = $dom->saveHTML($childNode);
}