我正在组合一些 CSS 文件并将它们写入单独目录中的文件。我正在尝试替换相对 url()
值以使用新文件位置,忽略任何绝对 URL。这是一些示例 CSS:
#TEST {
background:url(test.jpg);
background:url( 'test.jpg' );
background:url("test.jpg" );
background:url(http://example.com/test.jpg);
background:url('https://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(//example.com/test.jpg);
}
任何不以 http://
、https://
或 //
开头的都应该得到 $path
在它之前注入(inject)(只有前 3 个应该匹配)。
期望的输出:
#TEST {
background:url(/themes/default/css/test.jpg);
background:url( '/themes/default/css/test.jpg' );
background:url("/themes/default/css/test.jpg" );
background:url(http://example.com/test.jpg);
background:url('https://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(//example.com/test.jpg);
}
然而,this code匹配相反的:
$path = '/themes/default/css/';
$search = '#url\(\s*([\'"]?)((http(s)?:)?//)#';
$replace = "url($1{$path}$2";
$css = preg_replace($search, $replace, $css);
我知道您可以使用 !^(http)
之类的东西来不匹配以 http
开头的字符串,但是我已经尝试失败(我 === 不擅长正则表达式)。我一直在使用 online regex tester弄清楚这一点,但我真的被困住了。
这可能不是我用来解决实际问题的方法(确保路径在编译后的 CSS 中有效)但是任何人都可以帮助我解决这个正则表达式问题,或者有更好的解决方案吗?
最佳答案
您快完成了 - 您所追求的“不匹配的字符串开头”称为“负前瞻”,看起来像 (?!http)
。
所以对于 url\(
后面没有 \s*['"]?(https?:)?//
,你这样做:
url\((?!\s*['"]?(http(s)?:)?//)
(我保留了 (s)
捕获组,以防您想捕获它,但您不需要 (s)
周围的那些括号;s?
与 (s)?
相同(如果您不关心捕获)。
查看实际效果 here .
编辑:
由于您想将 $path 放在引号(如果有)之后,我将正则表达式修改为:
url\((?!\s*['"]?(?:https?:)?//)\s*(['"])?
即删除了我不关心的所有捕获括号,并添加了一个 \s*(['"])?
来捕获它是什么类型的引用。
我认为它在键盘上 here ,但为了以防万一,这里是代码:
$path = '/themes/default/css/';
$search = '#url\((?!\s*[\'"]?(?:https?:)?//)\s*([\'"])?#';
$replace = "url($1{$path}";
关于php - preg_replace() 正则表达式以匹配 CSS 文件中的相对 url() 路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9798378/