问题
i need some help with a RegEx that should split cssText( not selector,but the part inside {} ) into assoc with key->value pairs array in PHP
Assuming the the selector part is removed and there is for instance this:
color: black;
font-family: \"Courier New\";
background: url(\"test.png\");
color: red;
Yes the string is escaped i did managed to do that when extracting the {} part.
BUT:
if background is dataURI or there is content prop set like those:
content:'1.test;2.blabla;';
background: white url('data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABl...') no-repeat scroll left top;
the splitting RegEx i use:
preg_match_all('/([\w-]+)\s*:\s*([^;]*)\s*;?/i', $css, $matches, PREG_SET_ORDER);
fails :(
I'm not pro in RegEx and need your advice on how to NOT brake on ';' appearance inside \"...\" inside the string.
It should be in the capturing group ([^;]*) which as i found means: Match any single character that is not ; and repeat that 0 or more times.
Thanks in advance!
回答1:
If this is not for learning purposes, I really would recommend using a library instead of re-inventing the wheel :) Something like https://github.com/sabberworm/PHP-CSS-Parser.
回答2:
If you don't care about comments you could use something like this to handle quoted content with escapes:
/([\w-]++) \s*+ : \s*+ ( (?: [^;'"]++ | "(?:[^"\\]|\\.)*+" | '(?:[^'\\]|\\.)*+' )*+ ) \s* ;?/x
(Don't forget to double+ escape the \\
when quoting in PHP.)
回答3:
I am crafting a simple parseCSS
function using a simple state machine. You can read the code and you can extend further to what you need. The complexity of the algorihm is O(N) where N is the length of the css.
function parseCSS($css)
{
// State variable
$isOption = true; $isValue = false; $isQuote = ''; $arr=array();
// Buffer variable
$option = ''; $value = '';
for($i = 0; $i < strlen($css); $i++) {
if ($isOption) {
if ($css[$i] == ':') {
$isValue = true; $isOption = false;
} else {
$option .= $css[$i];
}
} elseif ($isValue) {
if ($isQuote == $css[$i]) {
$isQuote = ''; $value .= $css[$i];
} elseif ($isQuote != '') {
$value .= $css[$i];
} else {
if (($css[$i] == "'") || ($css[$i] == '"')) {
$isQuote = $css[$i]; $value .= $css[$i];
} elseif ($css[$i] == ';') {
$arr[trim($option)] = trim($value);
$option = ''; $value = '';
$isOption = true; $isValue = false;
} else {
$value .= $css[$i];
}
}
}
}
return $arr;
}
$css = parseCSS
(
"content:'1.test;2.blabla;';
background: white url('data:image/png;base64,iVBORw0KGgoAA
AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABl...') no-repeat scroll left top;"
);
var_dump($css);
回答4:
Use this function
function BreakCSS($CSS) {
$results = array();
foreach(explode(';', $CSS) AS $attr)
if (strlen(trim($attr)) > 0) // for missing semicolon on last element, which is legal
{
list($name, $value) = explode(':', $attr);
$results[trim($name)] = trim($value);
}
return $results;
}
来源:https://stackoverflow.com/questions/18461775/split-css-inside-the-to-array-of-key-value-pairs