php - preg_replace() 正则表达式以匹配 CSS 文件中的相对 url() 路径

标签 php regex preg-replace

我正在组合一些 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/

相关文章:

php - 使用 ajax 和 php 改进轮询

php - 如何只删除字符串中的html标签?

java - Tuckey URL 重写中的转义问号(XML/Regex)

php - 从字符串中删除非文本字符(如表情符号)

php - 如何显示数据库中的最后五行

php - 插入和选择排序比较和交换时间是否相等?

php - Laravel 无法使用 Storage::('s3' )->delete($files) 删除远程 url 中的文件;但可以在使用 aws 命令时删除

python - 检查变量是否为 SRE_Match

php - 使用 preg_replace 在 PHP 字符串中查找电话号码的终极方法

php - preg_replace 问题