Php Regex替换CSS文件中的url

时间:2014-11-18 23:04:19

标签: php regex preg-replace

我正在将多个CSS文件压缩为一个并将新生成的css文件移动到 自己的文件夹这一举动扰乱了图像,@ import和字体路径。

有人可以看看这个,看看你是否可以设法修复以下路径。

$content ='
    @import url(comments.css);<br />
    @import url(../comments.css);<br />
    @import url(../../comments.css);<br />
    background:url(http://example.com/test.jpg);<br />
    background:url("http://example.com/test.jpg");<br />
    background:url( "//example.com/test.jpg" );<br />
    background:url(//example.com/test.jpg);<br />
    background:url(test.jpg);<br />
    background:url(images/test.jpg);<br />
    background:url(../images/test.jpg);<br />
    background:url(../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
  ';

$content .="
    background:url('http://example.com/test.jpg');<br />
    background:url('../images/test.jpg'  );<br />
";

$path = 'http://www.some.com/cached';
$re = "/url\\(\\s*[\\'\"]?\\/?(.+?)[\\'\"]?\\s*\\)/i"; 
$content = preg_replace($re, 'url('.$path.'/$1)', $content);

echo $content ;

实施例 http://sandbox.onlinephpfunctions.com/code/20668872e49ea96b57964a9ee7176a5bbd796a5c

期望的结果将是这个

@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
background:url(http://example.com/test.jpg);
background:url(http://example.com/test.jpg);
background:url(//example.com/test.jpg);
background:url(//example.com/test.jpg);
background:url(http://www.some.com/cached/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://example.com/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

Dagon正在思考,而OP只是想做所谓的事情所以我理解这两点。如果OP知道他们想要什么,并认为这是最好的解决方案,那么我会适应,尽管Dagon提出有效的分数。

下面应该适合你,但可能不会解释所有扭曲。我删除了example.com行只是为了让它更容易处理,而不必考虑一个正则表达式的所有可能性,但那就是我:

$content ='
    @import url(comments.css);<br />
    @import url(../comments.css);<br />
    @import url(../../comments.css);<br />
    background:url(http://example.com/test.jpg);<br />
    background:url("http://example.com/test.jpg");<br />
    background:url( "//example.com/test.jpg" );<br />
    background:url(//example.com/test.jpg);<br />
    background:url(test.jpg);<br />
    background:url(images/test.jpg);<br />
    background:url(../images/test.jpg);<br />
    background:url(../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
  ';

$content .="
    background:url('http://example.com/test.jpg');<br />
    background:url('../images/test.jpg'  );<br />
";

// contains example.com stuff
$matches1 = preg_replace($r1, '', $content);
// contains everything that does not contain example.com
$matches2 = preg_replace($r2, '', $content);

// replace relative paths
$output = preg_replace('~\((?:[./\s\'"]+|)~', '(http://www.some.com/cached/', $matches2);
// replace example.com stuff
$output .= preg_replace('~(?<!http:)//~', 'http://', $matches1);

print_r($output,false);

输出以下

@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
background:url(http://www.some.com/cached/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg' );
background:url(http://example.com/test.jpg);
background:url("http://example.com/test.jpg");
background:url( "http://example.com/test.jpg" );
background:url(http://example.com/test.jpg);
background:url('http://example.com/test.jpg');

答案 1 :(得分:1)

这可以做你想要的一切。

<?php
    // The content (heredoc syntax is cleaner when dealing with large strings)
    $content = <<<EOT
@import url(comments.css);<br />
@import url(../comments.css);<br />
@import url(../../comments.css);<br />
background:url(http://example.com/test.jpg);<br />
background:url("http://example.com/test.jpg");<br />
background:url( "//example.com/test.jpg" );<br />
background:url(//example.com/test.jpg);<br />
background:url(test.jpg);<br />
background:url(images/test.jpg);<br />
background:url(../images/test.jpg);<br />
background:url(../../images/test.jpg);<br />
background:url(../../../images/test.jpg);<br />
background:url(../../../images/test.jpg);<br />'
background:url('http://example.com/test.jpg');<br />
background:url('../images/test.jpg'  );<br />
EOT;

    // Set path
    $path = 'http://www.some.com/cached/';

    // Clear out the line breaks
    $content = str_replace('<br />', '', $content);

    // Clear out bogus whitespace
    $content = preg_replace('/\(\s+/', '(', $content);
    $content = preg_replace('/\s+\)/', ')', $content);

    // Clear out quotes
    $content = preg_replace('/(?:\'|\")/', '', $content);

    // Replaces repeating ../ patterns
    $content = preg_replace('/(?:\.\.\/)+(.*?\))/', $path.'$1', $content);

    // Prepend the path to lines that do not have a "//" anywhere
    $content = preg_replace('/(url\((?!.*\/\/))/i', '$1'.$path, $content);

    echo $content;

我从预期的结果中纠正了这两行:

background:url(/http://example.com/test.jpg);
background:url(/http://example.com/test.jpg);