Reguläre ausdrücke, css zusammenfassen mit php

Dieses Thema im Forum "Backend: PHP und MySQL" wurde erstellt von Chance, 13 August 2010.

  1. Chance

    Chance Member

    Ich stehe irgendwie auf dem Schlauch....
    Ich habe zwei CSS Dateien. Diese möchte ich in einer zusammenfassen.
    Vorlage + Änderung, also:
    Code:
    .test {color: green;}
    .test2 {color: red;}
    
    und
    Code:
    .test {color: yellow;}
    .test2 {color: red;}
    
    zu
    Code:
    .test {color: yellow;}
    .test2 {color: red;}
    
    .

    Dazu möchte ich die CSS auseinanderpflücken und per PHP wieder zusammensetzen.
     
  2. Nerdus

    Nerdus Halbgott in Schwarz

    … und wo genau hängst du da jetzt fest?

    Die einzelnen Selektoren stehen vor der offenen geschweiften Klammer und werden durch Kommata getrennt; die einzelnen Attribute stehen innerhalb der geschweiften Klammern und werden durch Semikola getrennt; innerhalb der Attribute werden Attributsnamen und -werte durch Doppelpunkte getrennt. Mit dem Wissen sollten sich die ersten Regeln zur “Zerlegung” doch eigentlich schon bauen lassen.
     
  3. Chance

    Chance Member

    Gedanklich an
    Code:
    .test, .test2  {
    color: yellow;
    }
    
    Und das ich kaum Ahnung von Rex habe :D
     
  4. Nerdus

    Nerdus Halbgott in Schwarz

    Aha. Dann lass’ mich meine Frage wiederholen:
     
  5. Chance

    Chance Member

    Beide CSS Dateien in einer Zusammenzuführen.
    Und die .test, test2 etc. zu beachten...

    Bzw. erstmal die .test von {...} zu trennen.
     
  6. rellek

    rellek relativ sensationell Mitarbeiter

    PHP:
    <?php


    $string 
    '.test {color: green;}
    .test2 {color: red;}'
    ;

    $res = array();

    $pattern '/([a-z0-9.#*]+) \{([a-z0-9\s,-;.%]+)\}/Uis';

    preg_match_all($pattern$string$res);

    print_r($res);

    /*
    Array
    (
        [0] => Array
            (
                [0] => .test {color: green;}
                [1] => .test2 {color: red;}
            )

        [1] => Array
            (
                [0] => .test
                [1] => .test2
            )

        [2] => Array
            (
                [0] => color: green;
                [1] => color: red;
            )

    )
    */

    ?>
     
  7. Nerdus

    Nerdus Halbgott in Schwarz

    Na also, damit kann man arbeiten ;)

    Der erste Schritt sollte eigentlich sein, die einzelnen Blöcke voneinander zu trennen, also aus
    Code:
    .test {color: green;}
    .test2 {color: red;}
    [code]einmal[code].test {color: green;}[code]und einmal[code].test2 {color: red;}[code]herauszuholen. Das geht am simpelsten mit [url='http://www.php.net/manual/de/function.preg-split.php']preg_split()[/url], als Trenner müsstest du einfach “}” angeben (und am besten zusätzlich das “PREG_SPLIT_NO_EMPTY”-flag setzen). Dann bekommst du ein Array, das ungefähr so aussehen sollte:[php]Array (
    	[0] => Array (
    		[0] => ".test {color: green;",
    		[1] => (Zeichenzahl des Strings, bin zu faul sie zu zählen)
    	),
    	[1] => Array (
    		[0] => ".test2 {color: red;"
    		[1] => (s.o.)
    	)
    )[/php]
    
    Auf die einzelnen Einträge des Arrays kannst du jetzt wieder preg_split() anwenden (diesmal mit “{”), um sie in Selektor und Anweisungen zu trennen …
    
    [quote='rellek','index.php?page=Thread&postID=4089#post4089']…[/quote]Mmh, ohne maulen zu wollen, aber für einen Anfänger in Sachen reguläre Ausdrücke dürfte es wohl ein bisschen schwierig werden, von dem Beispiel aus weiterzuarbeiten, oder?  8o
     
  8. rellek

    rellek relativ sensationell Mitarbeiter

    Und dabei ist der Ausdruck noch richtig harmlos. :D
     
  9. Chance

    Chance Member

    Danke :)

    War nah dran... irgendwie :D
    Code:
    ([\.\#\0-9a-zA-Z]+) {(.*?)}
    Habe nur immer Startschwierigkeiten ^^ .
     
  10. Chance

    Chance Member

    Ich habe es gelöst bekommen :)
    Für euch und die Googelden :D:

    $filecont ist der Inhalt der CSS Datei.

    Der Inhalt wird aufgesplittet, in ein Array gepackt und dann wieder umgewandelt.
    Das hat den Sinn, das die CSS Datei, die sonst der Browser zusammenfügt, schon zusammengefügt ist.
    Das Ergebnis ist am besten zu cachen... da die Umwabndlung noch nicht optimal ist.

    PHP:
    preg_match_all('/([a-z0-9.#-_:,\s*]+) \{([a-z0-9.\/()_\s,#-;.%]+)\}/isU'$filecont$TempPREG_SET_ORDER);

                
    $CSS = array();
                foreach (
    $Temp as $elem) {
                    if (
    strpos($elem[1],',') === false) {
                        
    $elem[2] = explode(';',$elem[2]);
                        foreach (
    $elem[2] as $elem2) {
                            
    $elem2 explode(':',$elem2);
                            if (isset(
    $elem2[1]) === true$CSS[trim($elem[1])][trim($elem2[0])] = trim($elem2[1]);
                        }

                     } else {

                            
    $Temp2 = array();
                            
    $elem[2] = explode(';',trim($elem[2]));
                            foreach (
    $elem[2] as $elem2) {
                                
    $elem2 explode(':',$elem2);
                                if (isset(
    $elem2[1]) === true$Temp2[trim($elem2[0])] = trim($elem2[1]);
                            }
                        if (
    count($Temp2) !== 0) {
                            
    $elem[1] = explode(',',$elem[1]);
                            foreach (
    $elem[1] as $elem3) {
                                if (isset(
    $CSS[trim($elem3)]) === false$CSS[trim($elem3)] = $Temp2;
                                else 
    $CSS[trim($elem3)] = array_merge($CSS[trim($elem3)],$Temp2);
                            }
                        }
                    }

                }

                
    $filecont '';
                foreach (
    $CSS as $key => $elem) {

                    
    $CSSItem = array();
                    foreach (
    $elem as $CSSkey => $CSSelem) {
                         
    $CSSItem[] = $CSSkey.':'.$CSSelem;
                    }
                    
    #."\n"
                    
    $filecont .= $key.'{'.implode(';',$CSSItem).';}'."\n";
                }

                echo 
    $filecont;
     
  11. Chance

    Chance Member

    Ausserdem noch 6kb gepart :)

    Was haltet ihr von der Idee überhaubt ?
     
  12. rellek

    rellek relativ sensationell Mitarbeiter

    Nicht so viel, ehrlich gesagt. Die 6 KB bekommst du bei ausreichender Grösse (und noch mehr) über GZ-Kompression und die Vererbung der CSS-Deklarationen ist Client-Sache, die man ohnehin nicht beeinflussen kann (und nebenbei bemerkt auch nicht ins Gewicht fällt).

    Dafür hast du den PHP-Aufwand immer - das ist imho schmerzhafter als die 6K.

    Aber RegEx halte ich für hingegen für ziemlich elementar, deshalb ist jede Beschäftigung damit goldrichtig ;)
     
  13. Titus

    Titus Goldmember

    keine Ahnung was du treibst, aber schaut lustig aus ^^

    blöde Frage wozu die CSS überhaupt erst lesen?

    warum schreibtst du nicht ein Styleeditor der per XML die im Style vorhanden klassen / IDs enthält kennt, dann evtl noch ein kürzel was diese Klasse macht, um eine kurze Version aller"nützlichen" CSS deklarationen darzustellen (im editor), alternativ alles was dir einfällt und somit der Editor hergibt

    checkbox davor und wenn die gesetzt ist wird der Wert übernommen, das ganze packst du (irgendwie) in die DB, möglichst das due nach identischen inhalten dann auch suchen kannst für die Ausgabe UND Bearbeitung im ACP (finde alle "blue" -> liste -> alle markieren -> neue farbe Update alle markierten, so kann man den einen oder anderen weglassen)

    nun kannst du für die Verwendung eine CSS ausgeben die nach deinem Bedürfnis kreiert ist, entweder sammelst du alle identischen Farbanweisungen heraus und packst das in eine Zeile, kombinirst das womöglich noch mit XY, oder was auch immer
    das wäre eine art statistische auswertung die du rechenintensiv vornehmen kannst, aber z.b. so eine möglichst kompakte CSS zu schreiben

    ist vermutlich einfacher als diesen kompressor zu schreiben das er sinnvoll funktioniert

    man wird bei CSS zwar sicher nicht um ein wenig eigene Schreibarbeit und Spezialeinträge herum kommen, aber das wär doch ein Styleeditor der recht passabel ist?!
     
  14. Chance

    Chance Member

    GZ Kompression ist auch aktiviert etc.
    Mir kommt es auf jedes Quentchen an.

    @Titus:
    Wäre dann Admin abhängig, oder ?
     
  15. Nerdus

    Nerdus Halbgott in Schwarz

    Ich finde die Idee nicht soo uninteressant, aber natürlich muss die Umsetzung entsprechend gut sein und man braucht eine Umgebung, in der so eine Spielerei auch tatsächlich sinnvoll ist. Wenn es sowieso nur eine einzelne CSS-Datei ist, die man damit ein bisschen “umsortiert”, dann ist der Effekt natürlich kaum der Rede wert. Wenn man aber zum Beispiel ein Dutzend CSS-Dateien hat, die man durch so eine (oder eine ähnliche) Funktion zu einer einzigen Datei zusammenfasst und den Inhalt so weit wie möglich komprimiert … Dann wird es schon interessanter, weil es nicht nur die Datenmenge deutlich reduzieren dürfte, sondern vor allem auch die Anzahl der Dateien, die überhaupt angefordert werden. Die Ergebnisse zu cachen sollte ja nicht so das große Problem sein, da sich die Inhalte von CSS-Dateien nicht am laufenden Band ändern.

    Dass das natürlich trotzdem eine Verbesserung ist, die hauptsächlich auf dem Papier besteht und in der Praxis kaum einen Unterschied darstellt, sollte eh klar sein.

    Sehr richtig :D
     
  16. Titus

    Titus Goldmember

    jein, wenn du es als eigenständige Anwendung erstellst ist das prinzipiell sogar auf einer HTML-Dateien basierten Website verwendbar, man bindet dann ja nur das Endprodukt, die CSS-Datei ein

    ich dachte du hast das für dein CMS gedacht, daher die IDee das gleich "richtig" zu machen statt diese komrimierungsspielerei

    die Verwaltung unterschiedlicher Stile könnte man auch in ebnen organisieren und bei der Auswertung nur bestimmte definitionen herausgeben, bzw Unterschiedliche CSS mit lediglich den Unterschieden zur BasisCSS
    was sicher hilfreich ist wenn man verschiedene Layouts verwendet - der Eingangsstil ist ja meist schon geladen, man bräuchte also nur die differenzwerte (ähnlich man beim vB ja auch unterstyles erstellen kann, mit dem Unterschied das man nicht das Ganze sondern nur die Unterschiede ausgibt)

    wobei dann immer zu beachten ist welche Hierarchie einzuhalten ist, wenn eine Optionenbox auf der Startseite anders aussieht als auf der Unterseite wäre nicht so prall das zusammen zu fügen
     

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deinem Erleben anzupassen und dich nach der Registrierung angemeldet zu halten.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden