0

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!

4
  • 1
    Does it need to be regular expression? or any solution is acceptable? Commented Aug 27, 2013 at 9:34
  • I've made some regex at this post, which does not some code to work not only regex: stackoverflow.com/questions/12872879/… Commented Aug 27, 2013 at 9:35
  • If you want to play with CSS and regex this could be relevant: stackoverflow.com/questions/15195750/… Commented Aug 27, 2013 at 9:35
  • 1
    can be anything that works in PHP... Commented Aug 27, 2013 at 9:36

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't want to use a parser because the CSS is already validated, comments are stripped and so on...it only needs to be spitted for further usage. thanks anyway!
@LiliputFX You would save so much time. If you still want to implement it yourself, I'd suggest looking at the CSS 2.1 spec so you don't miss anything.
1

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;
}

Comments

0

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.)

Comments

0

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);

1 Comment

Close to what i need but some how returns an empty array. Is there some idea why?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.