Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regular expression for media queries in CSS

I'm searching for a way to extract media queries from a CSS file.

/* "normal" css selectors

@media only screen and (max-device-width: 480px) {
    body{-webkit-text-size-adjust:auto;-ms-text-size-adjust:auto;}
    img {max-width: 100% !important; 
         height: auto !important; 
    }
}

@media only screen and (max-device-width: 320px) {
    .content{ 
        width: 320px;
    }
}

now I like to get only the media queries. I though the begin is always @media and the end of the search is always a curly bracket followed by some optional whitespace and another curly bracket.

The only thing I have is

preg_match_all('#@media ?[^{]+?{XXX#',$stylesheetstring, $result);

were XXX is the missing part I'm searching for.

The current one (without the X) only returns the first line (obviously)

like image 303
Xaver Avatar asked Jan 15 '23 14:01

Xaver


1 Answers

Assuming you want the entire media block, I don't think this is the right job for regex.

You could however, implement a simple parsing function:

function parseMediaBlocks($css)
{
    $mediaBlocks = array();

    $start = 0;
    while (($start = strpos($css, "@media", $start)) !== false)
    {
        // stack to manage brackets
        $s = array();

        // get the first opening bracket
        $i = strpos($css, "{", $start);

        // if $i is false, then there is probably a css syntax error
        if ($i !== false)
        {
            // push bracket onto stack
            array_push($s, $css[$i]);

            // move past first bracket
            $i++;

            while (!empty($s))
            {
                // if the character is an opening bracket, push it onto the stack, otherwise pop the stack
                if ($css[$i] == "{")
                {
                    array_push($s, "{");
                }
                elseif ($css[$i] == "}")
                {
                    array_pop($s);
                }

                $i++;
            }

            // cut the media block out of the css and store
            $mediaBlocks[] = substr($css, $start, ($i + 1) - $start);

            // set the new $start to the end of the block
            $start = $i;
        }
    }

    return $mediaBlocks;
}
like image 151
Supericy Avatar answered Jan 21 '23 13:01

Supericy