1

I have these CSS codes.

.class-1,
.class-2,
class-3 {
    }
.class-4,
class-5 {
}
.class-6,
class-7 {}
.not-empty-1 {font-size: 12;}
.not-empty-2 {
    font-size: 12;
}
.not-empty-3 {
font-size: 12;
}

I need to remove the CSS classes that don't have any properties.

I have tried this

.+\s{(\n.*|)}

https://regex101.com/r/8xFUDl/2

but it does not remove the previous classes like .class-1, .class-2, as you see in live example.

Any solution is appreciated.

9
  • I think that can be tricky, but for the current example perhaps like [^{}\r\n]+(?:\r?\n[^{}\r\n]+)*{\s*} regex101.com/r/QTzEu7/1 Commented Jan 27, 2020 at 7:55
  • Are you set on using regex for this? It might be easier using a tokenizer. Also, likely easier to debug and extend/change later. Commented Jan 27, 2020 at 7:55
  • @Cully Would you explain more. I am up for any solution which is possible in PHP. Commented Jan 27, 2020 at 7:56
  • 2
    @user3631047 I could post it, but looking at the pattern of anubhava I think that would be the better answer if that also works for you. Commented Jan 27, 2020 at 8:06
  • 2
    @Thefourthbird: ^(?:[^{}\r\n]*\R)*+[^{]+{\s*}\s* will be more efficient than what I posted earlier. Please post an answer as you were first to solve this. Making a pattern more efficient is a different issue :) Commented Jan 27, 2020 at 8:07

2 Answers 2

1

From the comments and credits for the final pattern to @anubhava, for the example data you could use:

^(?:[^{}\r\n]*\R)*+[^{}]+{\s*}\s*

Explanation

  • ^ Start of string
  • (?: Non capture group
    • [^{}\r\n]*\R Match 0+ times any char except { } or a newline and Unicode newline sequence
  • )*+ Close group and repeat 0+ times using a possessive quantifier
  • [^{}]+ Match 1+ times any char other than { or }
  • {\s*} Match { and } with whitespaces in between (Note that \s also matches the newlines)
  • \s* Match possible trailing whitespace chars

Regex demo

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

1 Comment

@vivek_23 That is why I added a comment in the answer to use [^{}]+ regex101.com/r/DcDFE2/1 I will update the whole pattern, thank you for noticing.
0

Since you tagged PHP, we can do a bit of string processing to make regex a bit simpler where we could just match a single .some_class{some_props} style and ignore all others who don't follow this property.

We can ignore all whitespaces, new lines and collect just text in a string with a space as a delimiter between each style. Now, we can explode on each one and see if it matches the style we want which has properties and collect only those and implode them later.

Snippet:

<?php

$str = '.class-1,
.class-2,
class-3 {
    }
.class-4,
class-5 {
}
.class-6,
class-7 {}
.not-empty-1 {font-size: 12;}
.not-empty-2 {
    font-size: 12;
}
.not-empty-3 {
font-size: 12;margin-top:25px;
}';

$new_str = '';

for($i=0;$i<strlen($str);++$i){
    if(strlen(trim($str[$i])) === 0) continue; // skip new lines,spaces, line feeds etc
    $new_str .= $str[$i];
    if($str[$i] == '}') $new_str .= ' ';
}

$results = [];

foreach(explode(" ",$new_str) as $css_style){
    if(preg_match('/^(.+?)\{(.+?)\}$/',$css_style,$matches)){
        $results[] = implode("\n",[$matches[1],"{\n ".$matches[2]."\n}"]);
    }
}


echo implode("\n\n",$results);

Demo: https://3v4l.org/67mXE

Comments

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.