Regex to get comments from a CSS

Asked

Viewed 121 times

2

I have this CSS:

:root{
    --bodyBackgroundColor: #ffffff; // pegar o comentário não importando o tamanho
    --bodyTextColor: #ffffff; // outro
    --buttonBorderFocus: #1d2124; // testando
}

Response handler:

preg_match_all('/\s*\\--([A-Za-z1-9_\-]+)(\s*:\s*(.*?);)?\s*/', $css, $resultado);

Desired answer:

[0] => Array
    (
        [0] => --bodyBackgroundColor: #ffffff; 

        [1] => --bodyTextColor: #212529;

        [2] => --buttonBorderFocus: #1d2124;

    )

[1] => Array
    (
        [0] => bodyBackgroundColor
        [1] => bodyTextColor
        [2] => buttonBorderFocus
    )

[2] => Array
    (
        [0] => : #ffffff;
        [1] => : #ffffff;
        [2] => : #1d2124;
    )

[3] => Array
    (
        [0] => #ffffff
        [1] => #ffffff
        [2] => #1d2124
    )

[4] => Array
    (
        [0] => pegar o comentário não importando o tamanho
        [1] => outro
        [2] => testando
    )

The preg_match_all is only printing the 0,1,2,3 array. I need it to print 4 as well - I’m actually only using array 1 and 3, because I’m going to use the comment as caption.

  • Explain your problem better and how we can help.

  • @Salatielqueiroz, ready edited the post

1 answer

1


Just add the two bars, the space after them and the rest of the text in regex:

preg_match_all('/\s*\\--([A-Za-z1-9_\-]+)(\s*:\s*(.*?);)?\s*\/\/\s*(.*)/', $css, $resultado);

Bars shall be written as \/ not to be confused with the regex delimiters (the bars at the beginning and end, which only delimit but are not part of the regex itself).

Then I put \s* (zero or more spaces) because I don’t know how many spaces you can have after the bars. Then I use (.*) (zero or more occurrences of any character). As by default the . does not consider line breaks, it takes everything that is after the bars until it finds a line break.

The result is (output below obtained with var_dump($resultado)):

array(5) {
  [0]=>
  array(3) {
    [0]=>
    string(81) "
    --bodyBackgroundColor: #ffffff; // pegar o comentário não importando o tamanho"
    [1]=>
    string(39) "
    --bodyTextColor: #ffffff; // outro"
    [2]=>
    string(46) "
    --buttonBorderFocus: #1d2124; // testando"
  }
  [1]=>
  array(3) {
    [0]=>
    string(19) "bodyBackgroundColor"
    [1]=>
    string(13) "bodyTextColor"
    [2]=>
    string(17) "buttonBorderFocus"
  }
  [2]=>
  array(3) {
    [0]=>
    string(10) ": #ffffff;"
    [1]=>
    string(10) ": #ffffff;"
    [2]=>
    string(10) ": #1d2124;"
  }
  [3]=>
  array(3) {
    [0]=>
    string(7) "#ffffff"
    [1]=>
    string(7) "#ffffff"
    [2]=>
    string(7) "#1d2124"
  }
  [4]=>
  array(3) {
    [0]=>
    string(45) "pegar o comentário não importando o tamanho"
    [1]=>
    string(5) "outro"
    [2]=>
    string(8) "testando"
  }
}

One detail is that the above regex assumes that there will always be a comment. But if this is optional, just put everything in parentheses and add ? at the front (as this makes the section optional):

preg_match_all('/\s*\\--([A-Za-z1-9_\-]+)(\s*:\s*(.*?);)?\s*(?:\/\/\s*(.*))?/', $css, $resultado);

I also used (?: to the parentheses, for thus they become a catch group and its contents are not returned in the result array (if you do not have the ?:, another item is created in the array $resultado, containing the bars and the comment).


So you don’t have to write the bars like \/\/, it is possible to change the delimiters to some other character. In this case, I have chosen { and }, since they do not occur in regex. Thus, I no longer need to escape the bars (I can write them without the \):

preg_match_all('{\s*\\--([A-Za-z1-9_\-]+)(\s*:\s*(.*?);)?\s*(?://\s*(.*))?}', $css, $resultado);

PS: if you’re gonna do Parsing of a complete CSS, you might want to use parsers specific for the task.

For this specific string, whose format is simpler and more controlled, regex works smoothly. But if you have a full CSS, the regex will be much more complex, to be able to deal with every possible case.

  • 1

    Very understanding. + 1

  • @hkotsubo next I edited a little code to get the --bodyBackgroundColor: #ffffff; /test test/ because the css comments are // '/\s\--([A-Za-z1-9_-]+) s:\s*(.?);?\s/*(.)*//' now I used (?: '/(?: s\--([A-Za-z1-9_-]+) s*: s*(.?);?\s/*(.*)*/)/' not to create array 0 and still took

  • @Felipekusk I think that resolves. But if the comments extend over several lines, there gets more complicated

Browser other questions tagged

You are not signed in. Login or sign up in order to post.