Eduardo SR
Eduardo SR

Reputation: 57

PHP RegEx: Remove CSS rules, except if contain specific string

I'm struggling to match and keep all CSS rules containing the string 224,13,78.

Sample input:

h1 {
    color: rgb(224,13,78);
}


h1 {
    display: block; /* Delete this whole block */
}


#test-color {
    color: rgb(224,13,78);
}    


.test-position {
    position: absolute; /* Delete this whole block */
}


.test-bg-color {
    background-color: rgba(224,13,78,0.5);
}


@media ( max-width: 1200px ) {
    .test-color {
        color: rgb(224,13,78);
    }

    .test-position {
        overflow: hidden; /* Delete this whole block */
    }
}

Desired output:

h1 {
    color: rgb(224,13,78);
}


#test-color {
    color: rgb(224,13,78);
}


.test-bg-color {
    background-color: rgba(224,13,78,0.5);
}


@media ( max-width: 1200px ) {
    .test-color {
        color: rgb(224,13,78);
    }
}

Is there a handy regex that solves my problem?

For reference, I found this solution, but it matches the property name, not the value:

Find: \{.*(font-size\:\s*\d+px\;).*\}?

Replace: \{ $1 \}

And also this JavaScript solution that does the same:

What is RegEx to remove css keeping font size

I accept a JavaScript solution too, but PHP is preferable.

Thank you all in advance.

Upvotes: 1

Views: 313

Answers (1)

revo
revo

Reputation: 48701

Try the following regex:

\h*+[^\s{}][^{}]*{(?:[^{}](224,13,78)?)++[^{}]*+}(?(1)(*SKIP)(*F))\R*

See live demo here

What it does is trying to match a sequence of characters 224,13,78 in a {...} block. If it matches it holds the value in the first capturing group. Then later we say if 1st capturing group was successful in matching, then skip over whatever has been matched by:

(?(1)(*SKIP)(*F))

otherwise the whole match doesn't contain the desired characters and engine won't skip over it. We now only need to replace matched blocks with nothing:

$css = preg_replace('~\h*+[^\s{}][^{}]*{(?:[^{}](224,13,78)?)++[^{}]*+}(?(1)(*SKIP)(*F))\R*~', '', $css);

Upvotes: 1

Related Questions