You can do this:
$pat = '~(?>/\*(?>[^*]++|\*(?!/))*+\*/|{[^}]*+})(*SKIP)(?!)|[^\s,{/][^,{/]++~';
$css = preg_replace($pat, '#holder $0', $css);
The idea is to avoid comments and content inside curly brackets, then you can easily find all selectors with [^\s,{/][^,{/]++
.
To do that you put in a group the subpatterns for comments (i.e. /\*(?>[^*]++|\*(?!/))*+\*/
) and for content inside curly brackets (i.e. {[^}]*+}
), then you force the pattern to fail and forbid backtracking in the matched substrings.
(*SKIP)(?!)
is used for that. (*SKIP)
forbid to backtrack in all the matched content on his left if the subpattern will fail later. (?!)
forces the subpattern to fail ("not followed by nothing" is always false).