4

Let's say I have a css file as shown...

span {
    //whatever
}

.block {
    //whatever
}

.block, .something {
    //whatever
}

.more,
h1,
h2 {
    //whatever
}

I want to extract all class names and put it into an array, but I want to keep the structure, so the array will look like...

["span", ".block", ".block, .something", ".more, h1, h2"]

So there are four items.

This is my attempt...

$homepage = file_get_contents("style.css");

//remove everything between brackets (this works)
$pattern_one = '/(?<=\{)(.*?)(?=\})/s';

//this regex does not work properly
$pattern_two = "/\.([\w]*)\s*{/";

$stripped = preg_replace($pattern_one, '', $homepage);
$selectors = array();
$matches = preg_match_all($pattern_two, $stripped, $selectors);

what is the proper regex to use for pattern 2?

16
  • span is not a class though. Do you want all identifiers? Commented Oct 5, 2016 at 18:35
  • you might be looking for something like phpquery: github.com/punkave/phpQuery Commented Oct 5, 2016 at 18:35
  • @Thomas, phpQuery doesn't parse css files and extract the identifiers... you should double check it. Commented Oct 5, 2016 at 18:36
  • @chris85 yes all identifiers Commented Oct 5, 2016 at 18:37
  • 1
    Maybe regex101.com/r/uoqJKK/3? Commented Oct 5, 2016 at 18:40

1 Answer 1

6

Like this?

<?php
$css = "span {
    //whatever
}

.block {
    //whatever
}

.block, .something {
    //whatever
}

.more,
h1,
h2 {
    //whatever
}";

$rules = [];

$css = str_replace("\r", "", $css); // get rid of new lines
$css = str_replace("\n", "", $css); // get rid of new lines

// explode() on close curly braces
// We should be left with stuff like:
//   span{//whatever
//   .block{//whatever
$first = explode('}', $css);

// If a } didn't exist then we probably don't have a valid CSS file
if($first)
{
    // Loop each item
    foreach($first as $v)
    {
        // explode() on the opening curly brace and the ZERO index should be the class declaration or w/e
        $second = explode('{', $v);

        // The final item in $first is going to be empty so we should ignore it
        if(isset($second[0]) && $second[0] !== '')
        {
            $rules[] = trim($second[0]);
        }
    }
}

// Enjoy the fruit of PHP's labor :-)
print_r($rules);
Sign up to request clarification or add additional context in comments.

8 Comments

Shortcut $css = str_replace(array("\r", "\n", "\t", " ") , "", $css); , or even $css = preg_replace('/\s+/', '', $css);
@chris85 Excellent suggestion but I wanted to keep it verbose for newbie Googlers :-)
@MonkeyZeus this basically works, but just one small issue, the spaces are removed so the css identifier .block .something becomes .block.something for example. I don't mean to be anal but this is sort of an issue
@Bolboa Another thing to consider is that this does not handle comments outside of the curly braces so something can be done in $rules[] = trim($second[0]); but I am not going to figure it out right now. Try my code against BootStrap's CSS file and you will see what I am talking about.
@MonkeyZeus yeah it does not consider keyframes and such but I altered your code to fix it. Thanks
|

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.