如何使用正则表达式使这些相对URL绝对?

时间:2011-01-04 19:19:05

标签: php regex

我需要处理CSS文件以使任何相对路径(使用url())绝对。它应该匹配单引号或双引号中的URI,或者不带引号。不应引用替换。

E.g。

url(/foo/bar.png) --> url(/foo/bar.png) [unchanged]
url(foo/bar.png) --> url(/path/to/file/foo/bar.png) [made absolute]
url("foo/bar.png") --> url(/path/to/file/foo/bar.png) [made absolute, no quotes]
url('foo/bar.png') --> url(/path/to/file/foo/bar.png) [made absolute, no quotes]

我尝试了许多不同的模式,包括/和以下的许多变体的前瞻。

$dir = dirname($path);
$r = preg_replace('#url\(("|\')?([^/"\']{1}.+)("|\')?\)#', "url(/$dir/$2)", $contents);

似乎无法正确行事。有什么帮助吗?

4 个答案:

答案 0 :(得分:1)

我想这应该这样做:

$r = preg_replace('#url\(("|\'|)([^/"\'\)][^"\'\)]*)("|\'|)\)#', 'url(/'.$dir.'/$2)', $contents);

答案 1 :(得分:0)

你可以简化两件事。首先匹配引号,您应该使用["']?而不是组。并且为了检测相对路径名,检查是否存在字母,而不是没有斜线。

preg_replace('#url\(  [\'"]?  (\w[^)"\']+)  [\'"]?  \)#x'

我正在使用)来检测大括号的结尾,而不是.+。虽然仅列出[\w/.]+

等允许的字符会更加健壮

答案 2 :(得分:0)

以下内容如何:

$pattern = '#url\([\'"]?(\w[\w\./]+)[\'"]?\)#i';

$subjects = array(
  'url(/foo/bar.png)',
  'url(foo/bar.png)',
  'url("foo/bar.png")',
  'url(\'foo/bar.png\')',
);

foreach ($subjects as $subject) {
  echo "$subject => ", preg_replace($pattern, "url(/path/to/$1)", $subject), "\n";
}

输出以下内容:

url(/foo/bar.png) => url(/foo/bar.png)
url(foo/bar.png) => url(/path/to/foo/bar.png)
url("foo/bar.png") => url(/path/to/foo/bar.png)
url('foo/bar.png') => url(/path/to/foo/bar.png)

答案 3 :(得分:0)

$dir = dirname($path);
$r = preg_replace('#url\(([\'"]?)([^/].*?)\1\)#', "url(/{$dir}/$2)", $contents);
  • 匹配url
  • match open paren
  • open capture group 1
  • 匹配'或“零或一次
  • 关闭捕获组1
  • open capture group 2
  • 匹配一个不是/
  • 的字符
  • 不合理地匹配零个或多个字符
  • close capture group 2
  • 匹配捕获组1中捕获的任何内容(这确保了相同的引用匹配,并且如果1没有捕获引号则有效)
  • 匹配关闭paren

捕获第2组包含目标数据。