0

I'm trying to parse CSS with Regex and replace specific values in PHP.

Currently I've been able to parse the CSS files using the "CSS Parser" class found here.

I've been able to create simple regex as I'm not too advanced, that doesn't account for quirks like spacing.

Example

.marked     p

Would not be parsed, so I had to scrap it.

Is there an available Regex that can be used in conjunction with preg_replace that can acheive this?

3
  • catswhocode.com/blog/…
    – swordfish
    Commented Aug 29, 2011 at 7:07
  • Can you give us the pattern you have so far? Commented Aug 29, 2011 at 7:18
  • Concretise. Your question says CSS attribute, but you are showing a selector. Also CSS can be matched with a regex easily, but replacement can be more involving if the remainder needs to be preserved. For multiple spaces use \s+
    – mario
    Commented Aug 29, 2011 at 7:26

1 Answer 1

1

This pattern finds all the selectors and turns the rules into key-value arrays. It should work on wellformed CSS, otherwise some tweaking might need be done.

The idea is that in CSS there will not be anything but selectors between the brackets of rules. It searches for a string until it comes to a start-bracket and interprets that as a selector. So it basically searches for "not {", and when it has come to a { it knows it's found a selector. Because of this it might not properly handle @imports but that can be accounted for also.

The code is from my CSS Compiler and parser which has taken a lot of ideas from Andreas Lagerkvist

function callback($match)
{
    // Normalize whitespace from selector
    $selector = trim(preg_replace('/\s\s+/', ' ', $match[1]));

    // Turn the rules into key-value array
    $rules_str = str_replace(array('{', '}'), '', trim(preg_replace('/\s\s+/', ' ', $match[2])));
    $rules_pieces = explode(';', $rules_str);
    $rules = array();

    foreach ( $rules_pieces as $rule )
    {
        // No key-value pair?
        if ( ! strstr($rule, ':') ) continue;

        list($key, $value) = explode(':', trim($rule));
        $rules[$key] = trim($value);
    }

    // Do some stuff
    echo $selector . PHP_EOL;
}

$css = "
    body {
            font: foo; size: 1px; 
    }

    #foo .bar div {
            foo: bar;
            foooo: bar;
    }  

    #foo    .bar div { foo: bar; }
";

preg_replace_callback('/([^{;]+)(\{[^}]+\})/', 'callback', $css);

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.