[RegExp]CSS Parsen

Pagina: 1
Acties:

  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
Ik ben bezig met een PHP CSS parser (moet uiteindelijk VB worden, maar dat doet er niet toe). Na talloze sites over RegExps doorgeplozen te hebben zit ik nog steeds met m'n handen in het haar. Ik wil het commentaar (formaat: /* comment */) eruit strippen. Een voor de hand liggende regexp is de volgende (PCRE):
PHP:
1
$css = preg_replace('/\/\*.+\*\//', '', $css);

Met natuurlijk het probleem dat 'ie greedy is en bij meerdere commentaarblokken ook hele stukken CSS mee wegstript.
PHP:
1
$css = preg_replace('/\/\*[^\*\/]+\*\//', '', $css);
Werkt ook niet, omdat er in het commentaar ook de tekens '*' en '/' kunnen voorkomen, alleen niet de letterlijke string '*/'.

Hoe kan ik nu aangeven dat de letterlijke string '*/' niet mag voorkomen binnen een comment? Of is er een manier om die greediness in preg_replace uit te zetten?

Dato DUO synth voor twee


  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
Opgelost:
PHP:
1
$css = preg_replace('/\/\*.+?\*\//', '', $css);

Topic is gereport om te sluiten

Dato DUO synth voor twee


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 05:53

gorgi_19

Kruimeltjes zijn weer op :9

_/-\o_ dat je de oplossing nog even post. :) Alleen een topic gaat niet dicht omdat het opgelost is; misschien dat anderen nog andere toevoegingen en / of (betere?) oplossingen hebben. :)

Digitaal onderwijsmateriaal, leermateriaal voor hbo


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

DiMension schreef op 24 mei 2004 @ 18:50:
Opgelost:
PHP:
1
$css = preg_replace('/\/\*.+?\*\//', '', $css);

Topic is gereport om te sluiten
Kan dat niet beter zo zijn?
PHP:
1
$css = preg_replace('/\/\*.*?\*\//', '', $css);

Voor het geval dat er nix tussen /* en */ staat? :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
NMe84 schreef op 24 mei 2004 @ 19:12:
Kan dat niet beter zo zijn?
PHP:
1
$css = preg_replace('/\/\*.*?\*\//', '', $css);

Voor het geval dat er nix tussen /* en */ staat? :P
Je hebt gelijk, da's beter.

Ik zat trouwens eerst de verkeerde kant op te zoeken, omdat ik dacht dat het laatste gedeelte (\*\/) greedy was, terwijl de .* dat is.

Dato DUO synth voor twee


  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
Nu het topic toch open blijft: ik loop tegen meer moeilijkheden aan. Voor de geïnteresseerden zal ik m'n problemen (en hopelijk oplossingen) hier verder uiteenzetten.

Om selectors van properties/values te scheiden gebruik ik de volgende regexp:
PHP:
1
preg_match_all("/\s*(.+?)\s*\{\s*([^}]*)\s*\}\s*/", $css, $matches);


Deze matcht een string zonder whitespace (selector), en vervolgens de waarden binnen de opeenvolgende accolades (de properties en waarden). Echter, zou deze ook moeten werken als er een sluitende accolade '}' voorkomt binnen enkele of dubbele quotes (in een string is het geen afsluiter van een blok). Hoe kan ik dat erin verwerken?

[ Voor 100% gewijzigd door David op 25-05-2004 00:20 ]

Dato DUO synth voor twee


  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
Misschien even een wat duidelijkere uitleg. Het volgende is geldig in CSS:[code]body { font-family: Verdana, "Accolade {} Sans", sans-serif; margin: 0 }[/body]

De RegExp die ik nu heb:
PHP:
1
preg_match_all("/([^;]*?):([^;]*);?/", $matches[1][$key], $items);
Kapt het blok logischerwijs op de eerste sluitende accolade af:
code:
1
2
3
4
[body] => Array
        (
            [font-family] => Verdana, "Accolade {
        )

Dit is niet wat ik wil, omdat binnen enkele of dubbele quotes alle waarden zouden mogen voorkomen. Maar ook greediness is hier niet gewenst: hij zou alle CSS-blokken 'opslokken', terwijl dit niet de bedoeling is. Hoe moet ik m'n regexp verder uitbouwen?

Dato DUO synth voor twee


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

Ik denk dat je voor zoiets complex beter een stack based parser kan maken, zoals dat ook vaak gebruikt wordt bij UBB code implementaties.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

NMe84:
Ik denk dat je voor zoiets complex beter een stack based parser kan maken, zoals dat ook vaak gebruikt wordt bij UBB code implementaties.
Je hebt geen stack nodig, want de structuren binnen CSS kunnen niet genest worden. Je parser hoeft alleen maar een state bij te houden, om de globale structuur uiteen te rafelen. Je kunt dan twee dingen doen:
[list=1]• Alleen onderscheid maken tussen selector (bijvoorbeeld div.piet a:hover), body (bijv. { font-size:12px; } en string (bijv. "Accollades {}")
• Onderscheid maken tussen alle mogelijke states en de parser iets intelligenter maken door ook de properties / values meteen te parsen en alvast uit te zoeken wat de verschillende delen de selector zijn (classnames, id's, parents, pseudo-selectors, etc).

In ieder geval kom je daar met regular expressions niet zo eenvoudig uit. Wat wel handig is, in dit geval, is in plaats van karakter-voor-karakter de string te doorlopen gewoon op blokken te matchen. Zo is een selector bijvoorbeeld "alles totaan de eerstvolgende '{' " en een property alles totaan de eerstvolgende ":". (Er vanuit gaande dat je niet van plan bent CSS te valideren, want dan wordt het weer een stukje complexer)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • David
  • Registratie: Februari 2001
  • Laatst online: 18-05 21:36
Het gaat om een HTML/CSS-editor, die niet hoeft te validaten en in eerste instantie niet een met ingewikkelde selectors om hoeft te kunnen gaan.

Wat je dus zegt is dat ik beter het beter kan laten om alles in één regexp uit te pluizen, maar de CSS op te delen in hapklare brokken die ieder een VIP-behandeling krijgen. Lijkt me redelijk.

Dato DUO synth voor twee

Pagina: 1