1

I'm trying to get css selector + styles with a regexp but there is always a problem...

So do you have an idea (exemple ?) of a regexp do get this:

array(
[0] => "div {
    background: red;
    color: blue;
}",
[1] => "section {
    /* comment with bad idea } <- this break regexp [^}]+ */
    background: blue;
    color: red;
}"
);

fom this css:

div {
    background: red;
    color: blue;
}

section {
    /* comment with bad idea } <- this break regexp [^}]+ */
    background: blue;
    color: red;
}

Thx

3
  • I would start by Googling PHP Parse CSS, check out the solutions available, and see whether they are smart enough to catch this case Commented Nov 27, 2013 at 16:40
  • xkcd.com/1171 clear enough Commented Nov 27, 2013 at 17:45
  • possible duplicate of parsing a css file with sabberworm/PHP-CSS-Parser Commented Nov 27, 2013 at 18:31

3 Answers 3

1

How about:

\S+\s*{(.*?)}(?![^*]*\*/)

RegExr Example

Explanation:

\S+\s*       put your selector regex in place of this 
{(.*?)}      lazy match everything to a } 
(?![^*]*\*/) check that the next * after the } is not the start of a */

This will not match styles that are completely commented out. e.g /* div { ... } */ but it's unclear what you would want to happen in this case anyway.

Keep using whatever you're using to match the selectors instead of \S+\s* (which I just used for examples sake).

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

2 Comments

You are probably not too far... I preg_split keeping separator, so I removed "(" & ")" \S+\s*{.*?}(?![^*]**/) Now, my probleme is "/* fake selector {} */"
Hey Jordan, I assume that /* fake selector {} */ isn't within another style. You're right that this breaks the regex. tntu is correct, trying to accomplish this in regex has proven futile - I've tried all sorts. Comments outside of the regex containing { in this case (or } in other cases) break every variation I could think of :(
0

Regular expression will always fail because you have the } inside the comment.

It would only work if you ran a regular expression that removes all comments before the one that matches the styles.

5 Comments

One can construct a regex that understands comments between declarations. It's just unreasonable effort.
Actually NO you cannot. Because regular expressions, though a great tool, are still limited in certain aspects. What if he decided to comment an entire style, or who knows. Regular expressions are not good for this kind of things. He would better use a parser. Google: php css parser.
A recursive regex with named subroutines can. But yes, a readymade parser is significantly less effort.
As far as I know PHP cannot do that. Perl can though. But this is a PHP question.
@tntu, semi-confident I may have found a solution.
-1

I finally did it by another way. First, I start by quoting the undesired symbols with these regex

string = string
.replace(/(')([^']*)(')/ig, function(found){

    return found.replace(/([\[\]\s\,\#\.\:\>\~])/ig, "\/\/$1\\\\");

})
.replace(/(\")([^\"]*)(\")/ig, function(found){

    return found.replace(/([\[\]\s\,\#\.\:\>\~])/ig, "\/\/$1\\\\");

});

Then, I split the string with another regexp:

string = string.split(/(?!\/\/)([\s\>\,])(?!\\\\)|(?=(?!\/\/)[\#\.\[\:](?!\\\\))/ig);

And, to finish, if( string[x].match(/^[a-z]+$/ig) ){..}; it is a tagName

If you see something bad, I'm listening to you.

Edit :

Oups ! I forgot my answer was about php, sorry. But I apply the same method for php, except lookBefore simplify and reduce the regexp to only one, then split...

J

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.