0

假设我们的$plain_css变量中有一些 CSS:

.slide-pause {
  cursor: url(http://example.com/img/bg/pause.png),url(http://example.com/img/bg/pause.png),auto;
}
.something {
  background-image: url('http://example.com/img/bg/beautiful.png'); // We have Quotes here
}

我需要从此 CSS 获取所有 URL。

这就是我试图实现这一目标的方式:

preg_match_all('!url\(\'?http://example.com/.*\)!', $plain_css, $matches);

什么$matches返回:

array
  0 => 
  array
    0 => string 'url(http://example.com/img/bg/pause.png),url(http://localhost/site/img/bg/pause.png)'
    1 => string 'url(http://example.com/img/bg/beautiful.png)'

我需要它返回:

array
  0 => string 'url(http://example.com/img/bg/pause.png)'
  1 => string 'url(http://example.com/img/bg/pause.png)'
  2 => string 'url(http://example.com/img/bg/beautiful.png)'
4

2 回答 2

3

你是贪婪的牺牲品。.*尽可能匹配。将其替换.*?为使其不贪心以进行快速修复。或者禁止)重复字符(这通常是首选 - 它更明确和更有效):

preg_match_all('!url\(\'?http://example.com/[^)]*)!', $plain_css, $matches);

请注意,您无法说服preg_match_all以普通数组形式返回所有内容 - 您将始终得到一个嵌套数组(这对于捕获很重要)。但是您可以简单地从$matches[0].

于 2013-08-28T18:54:11.683 回答
2

你需要让你的重复量词变得懒惰(默认是贪婪的):

preg_match_all('!url\(\'?http://example.com/.*?\)!', $plain_css, $matches);

*这里唯一的变化是我在重复量词之后添加了一个问号。通常,重复是贪婪的:也就是说,它们匹配尽可能多的字符(并且仍然满足表达式)。在这种情况下,*量词的贪婪消耗了url输入字符串中的两个表达式。更改为惰性量词可以解决问题。

处理此问题的另一种方法是使用否定字符类而不是.元字符(它匹配除换行符以外的任何字符):

preg_match_all('!url\(\'?http://example.com/[^)]*\)!', $plain_css, $matches);
于 2013-08-28T18:53:26.243 回答