Explode or similar not break enclosed delimiters

Asked

Viewed 164 times

1

I’m developing a CSS parser, but when it arrives in a block like this:

    height: 100%;
    background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
    display: block;

First I have to normalize with:

$rules = str_replace(array("\n","\r"), array('',''), $rules);

// Que me retorna:
// height: 100%; background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); display: block;

(because files can come with rules on the same line)

And when applying:

$rules = explode(';',$rules);

the explosion breaks in ; inside the string "...gif;Base64..."

I was able to "solve" by applying str_replace to ;base64 for -base64 and then when rendering the css, I replace -base64 for ;base64. Gambiarra level 9000

This obviously limits to just this situation, and I need a broader solution, how not to break if the ; is inside ", ', ( or )

I’ve tried with str_getcsv and it doesn’t work...

Pastebin of the complete function.

  • 2

    In that case, I believe you can blow up in the ;\n,

  • @Gabrieltadramainginski I have to normalize before the explosion and remove all r n, because sometimes the file already comes with all the rules in one line...

  • The preg_split() of the same problem?

  • @lost Yes, preg_split returns exactly the same thing that explodes it...

  • Will the data before ";" always be images? (jpg, gif, etc)

  • @Mukotoshi Currently only this line presented the problem, but I do not know if the customer will not use other similar lines in the future.

  • Does it help using the Intel? $string = explode( "\n" , $css ) and use the line $string[1] // background-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");, then you can make it easier by using an ER

  • @Papacharlie The function is used in several different files with hundreds of CSS selectors, some already minimized and no line breaks between the rules, I can not rely on line breaking to separate the rules...

  • 2

    It’s over 9000! I think in your case, it pays not to use explodes, but to make a small parser. I would suggest changing the title of the question to "How to use a Explode, or similar to not break enclosed delimiters", as it makes room for other solutions.

Show 4 more comments

1 answer

1

I got a broader solution using a REGEX that replaces all ; who are enclosed within ( ) for: [ENCLOSED_DELIMITER], and after breaking with the explode, replaces it back to ;

$teste = 'height: 100px; background: url("data:image/gif;base64;//PRIMEIRO;"); display: block; background: url(\'data:image/gif;base64,//SEGUNDO\'); display: block; background: url(data:image/gif;base64,//TERCEIRO);';

$teste = preg_replace_callback(
            '/\([^\)]*\)/',
            function ($matches) {
                return str_replace(';', '[ENCLOSED_DELIMITER]', $matches[0]);
            },
            $teste);

$teste = explode(';', $teste);

foreach($teste as &$v) $v = str_replace('[ENCLOSED_DELIMITER]', ';', $v);

print_r(array_filter($teste));

// Retorno:

Array
(
    [0] => height: 100px
    [1] =>  background: url("data:image/gif;base64;//PRIMEIRO;")
    [2] =>  display: block
    [3] =>  background: url('data:image/gif;base64,//SEGUNDO')
    [4] =>  display: block
    [5] =>  background: url(data:image/gif;base64,//TERCEIRO)
)

It’s still a gambit, but at least it’s wider.

If anyone knows of other possibilities ; in the CSS rules, please comment below.

Follows the Pastebin of the full parser for those interested.

  • heheeh.. now stands "Gambiarra level 9001"

Browser other questions tagged

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