【发布时间】:2012-05-26 03:32:23
【问题描述】:
我以为这会很简单,但我现在已经为此苦苦挣扎了一段时间。我知道那里有 CSS 解析器类可以实现我想要做的......但我不需要它们所拥有的 95% 的功能,所以它们并不是真正可行的,而且太重了。
我需要做的就是通过正则表达式提取 CSS 文件中使用的任何类和/或 ID 名称。这是我认为可以工作的正则表达式,但没有。
[^a-z0-9][\w]*(?=\s)
当针对我的样本运行时:
.stuffclass {
color:#fff;
background:url('blah.jpg');
}
.newclass{
color:#fff;
background:url('blah.jpg');
}
.oldclass {
color:#fff;
background:url('blah.jpg');
}
#blah.newclass {
color:#fff;
background:url('blah.jpg');
}
.oldclass#blah{
color:#fff;
background:url('blah.jpg');
}
.oldclass #blah {
color:#fff;
background:url('blah.jpg');
}
.oldclass .newclass {
text-shadow:1px 1px 0 #fff;
color:#fff;
background:url('blah.jpg');
}
.oldclass:hover{
color:#fff;
background:url('blah.jpg');
}
.newclass:active {
text-shadow:1px 1px 0 #000;
}
它确实符合我想要的大多数,但它也包括大括号并且与 ID 不匹配。连接时我需要分别匹配 ID 和类。所以基本上#blah.newclass 将是 2 个单独的匹配项:#blah AND .newclass。
有什么想法吗?
====================
最终解决方案
我最终使用了 2 个正则表达式,首先删除了 { 和 } 之间的所有内容,然后根据剩余的输入简单地匹配选择器。
这是一个完整的工作示例:
//Grab contents of css file
$file = file_get_contents('css/style.css');
//Strip out everything between { and }
$pattern_one = '/(?<=\{)(.*?)(?=\})/s';
//Match any and all selectors (and pseudos)
$pattern_two = '/[\.|#][\w]([:\w]+?)+/';
//Run the first regex pattern on the input
$stripped = preg_replace($pattern_one, '', $file);
//Variable to hold results
$selectors = array();
//Run the second regex pattern on $stripped input
$matches = preg_match_all($pattern_two, $stripped, $selectors);
//Show the results
print_r(array_unique($selectors[0]));
【问题讨论】:
-
为什么不使用complete CSS parser 来提取选择器?
-
CSS 解析器有什么问题?您是否运行过任何基准测试?不要仅仅因为您认为它“太重”而排除。
-
哈哈!我拼错了自己的名字……噗。而且我没有使用完整的 CSS 解析器,因为如上所述,它们对于我想做的事情来说太重和臃肿了……它们包含大量我永远不会使用的功能。如果我能解决这个问题,一个简单的单行正则表达式将是理想的。