Analyse CSS par regex
Je suis de la création d'un éditeur CSS et suis en train de créer une expression régulière qui peut obtenir les données à partir d'un document CSS. Cette regex fonctionne si j'en ai un bien, mais je ne peux pas le faire fonctionner pour toutes les propriétés. Je suis en utilisant preg/syntaxe de perl en PHP.
Regex
(?<selector>[A-Za-z]+[\s]*)[\s]*{[\s]*((?<properties>[A-Za-z0-9-_]+)[\s]*:[\s]*(?<values>[A-Za-z0-9#, ]+);[\s]*)*[\s]*}
Cas de Test
body { background: #f00; font: 12px Arial; }
Résultats Attendus
Array(
[0] => Array(
[0] => body { background: #f00; font: 12px Arial; }
[selector] => Array(
[0] => body
)
[1] => Array(
[0] => body
)
[2] => font: 12px Arial;
[properties] => Array(
[0] => font
)
[3] => Array(
[0] => font
)
[values] => Array(
[0] => 12px Arial
[1] => background: #f00
)
[4] => Array(
[0] => 12px Arial
[1] => background: #f00
)
)
)
Réel Résultat
Array(
[0] => Array
(
[0] => body { background: #f00; font: 12px Arial; }
[selector] => body
[1] => body
[2] => font: 12px Arial;
[properties] => font
[3] => font
[values] => 12px Arial
[4] => 12px Arial
)
)
Merci d'avance pour toute aide - cela a été source de confusion moi tout l'après-midi!
source d'informationauteur Ross
Vous devez vous connecter pour publier un commentaire.
Semble tout simplement trop complexes pour une seule expression régulière. Eh bien, je suis sûr qu'avec le droit extentions, un utilisateur avancé pourrait créer la bonne regex. Mais alors, vous auriez besoin d'un même utilisateur plus avancé pour le déboguer.
Au lieu de cela, je vous conseille d'utiliser une regex pour retirer les morceaux, puis tokenising chaque pièce séparément. par exemple,
Puis vous vous retrouvez avec le sélecteur et les attributs dans des champs distincts, puis diviser ceux-ci. (Même le sélecteur sera amusant à analyser.) Notez que même cela va avoir des douleurs si }'s peut apparaître à l'intérieur de guillemets ou de quelque chose. Vous pouvez, encore une fois, spire le diable hors de lui pour l'éviter, mais c'est probablement mieux éviter regex est complètement ici, et de les traiter par l'analyse d'un champ à un moment, peut-être en utilisant un appel récursif de la descente de l'analyseur ou yacc/bison ou quoi que ce soit.
Vous êtes en essayant de tirer structure de données, et pas seulement les valeurs individuelles. Les expressions régulières peuvent pourrait être douloureusement tendu pour faire le travail, mais vous êtes vraiment entrer dans l'analyseur territoire, et doit être à sortir les gros canons, à savoir les parseurs.
Je n'ai jamais utilisé l'analyseur PHP, outils de génération, mais ils ont l'air très bien après un peu de numérisation de la documentation. Découvrez LexerGenerator et ParserGenerator. LexerGenerator prendra un tas d'expressions régulières décrivant les différents types de jetons dans une langue (dans ce cas, CSS) et de cracher un peu de code qui identifie les différents jetons. ParserGenerator prendra une grammaire, une description de ce que les choses dans une langue sont constitués de ce que les autres choses, et cracher un analyseur de code qui prend un tas de jetons et renvoie un arbre de syntaxe (la structure de données que vous êtes après.
Ne pas utiliser votre propre regex pour l'analyse de CSS.
Pourquoi réinventer la roue alors qu'il est le code qui vous attend, prêt à l'emploi et (espérons-le) de sans bug?
Il y a généralement deux classes disponibles qui peuvent analyser CSS pour vous:
HTML_CSS paquet PEAR à pear.php.net
et
CSS Analyseur de classe à PHPCLasses:
http://www.phpclasses.org/browse/package/1289.html
Je déconseille l'utilisation de regex pour analyser CSS - en particulier dans la seule regex!
Si vous insistez sur le fait de faire l'analyse dans la regex, divisé en sensible sections - utiliser une regex pour diviser tous les
body{..}
blocs, puis une autre pour analyser lescolor:rgb(1,2,3);
attributs.Si vous êtes en train d'essayer d'écrire quelque chose "utile" (pour ne pas essayer d'apprendre des expressions régulières), pour un look prédéfinis, CSS analyseur.
J'ai trouvé cette cssparser.php qui semble fonctionner très bien:
..dont les résultats suivants:
L'analyseur est assez simple, il doit donc être facile de travailler sur ce qu'il fait. Oh, j'ai dû enlever les lignes lues
if($this->html) {$this->Add("VAR", "");}
(il semble être un débogage chose qui a été laissé dans)J'ai repris le script iciavec les modifications ci-dessus dans
Je suis en utilisant l'expression régulière ci-dessous et il réussit plutôt bien... bien sûr, cette question est vieux maintenant et je vois que vous avez abandonné vos efforts... mais au cas où quelqu'un d'autre de la traverse:
(hafta supprimer tous les /* commentaires */ de votre CSS d'abord pour être sûr)
J'ai écrit un bout de code qui traite facilement CSS. Tout ce que vous avez à faire est de faire quelques explose vraiment... Le $css variable est une chaîne de la CSS. Tout ce que vous avez à faire est de faire une
print_r($css)
pour obtenir un beau tableau de CSS, entièrement analysée.Vous donne ceci:
Construction de la réponse actuelle par Tanktalus il y a quelques améliorations et le bord en cas de note.
CSS Analyse Regex
Cette Regex va faire de l'espace de taillage et de hits sur les bord des cas énumérés dans cet exemple: https://regex101.com/r/qQRIHx/5
clé:des paires de valeurs; les Pièges de la Poursuite de l'Complexicated Regex
J'ai aussi commencé à essayer de travailler sur la délimitation de la clé:des paires de valeurs, mais rapidement vu dans le cas où il y avait plusieurs styles par sélecteur que les choses ont commencé à obtenir plus délicat que ce que je voulais. Vous pouvez afficher la version 1 de la regex où j'ai essayé de délimiter la clé:des valeurs et de la façon dont il a échoué avec de multiples déclarations ici: https://regex101.com/r/qQRIHx/1
Mise en œuvre
Comme d'autres l'ont mentionné, vous devez décomposer en plusieurs étapes, à analyser et à marquer votre css. Cette regex sera vous aider à obtenir les déclarations, mais vous devrez ensuite d'analyser ces.
Déclaration De L'Analyseur
Vous pouvez utiliser quelque chose comme cela pour analyser les déclarations d'après vous obtenez votre premier jeu de correspondances.
([^:\s]+)*\s*:\s*([^;]+);
Exemple: https://regex101.com/r/py9OKO/1/
Bord De Cas
L'exemple ci-dessus fonctionne très bien avec de multiples déclarations, mais il est possible que c'est juste 1 de la déclaration avec pas de point-virgule à la fin qui rendra à [plus] les navigateurs mais briser cette regex.
Constaté Des Cas
Vous pouvez aussi avoir besoin de compte pour les règles imbriquées dans le cas où il y a une requête de média. Dans ce cas, je voudrais essayer d'exécuter le fichier css correspondant regex contre les déclarations qui sont extraites. Si vous obtenez correspond vous pouvez exécuter la récursivité sur (même si je ne suis pas sûr qu'il y a des cas où vous auriez plus de 1 niveau imbriquée à la vanille CSS).
Les Cas De Bord
De demain Recherche
J'ai décidé d'utiliser à la place d'un mécanisme de prévention de package comme
css
oucssom
. Je sais que c'est en PHP, mais ça va faire beaucoup de levage lourd pour moi et gérer les cas de bord-je continuer à courir dans.Modifier:
J'ai fini par utiliser Jotform du public css.js de la bibliothèque. Il a vraiment une petite empreinte de pas qui était l'une des principales exigences que j'avais au moment de choisir les bibliothèques pour analyser CSS.
Essayer cette