Regex für passende CSS-Hex-Farben

Lesezeit: 4 Minuten

Ich versuche, eine Regex zu schreiben, die alle Hex-Farben aus dem CSS-Code extrahiert.

Das habe ich jetzt:

Code:

$css = <<<CSS

/* Do not match me: #abcdefgh; I am longer than needed. */

.foo
{
    color: #cccaaa; background-color:#ababab;
}

#bar
{
    background-color:#123456
}
CSS;

preg_match_all('/#(?:[0-9a-fA-F]{6})/', $css, $matches);

Ausgabe:

Array
(
    [0] => Array
        (
            [0] => #abcdef
            [1] => #cccaaa
            [2] => #ababab
            [3] => #123456
        )

)

Ich weiß nicht, wie ich angeben soll, dass nur die Farben abgeglichen werden, die mit Satzzeichen, Leerzeichen oder Zeilenumbrüchen enden.

  • Kümmern Sie sich nicht um Regex. Siehe die Antwort von @modu. if(ctype_xdigit($color) && strlen($color)==6).

    – Dan Bray

    1. November 2017 um 21:16 Uhr

Benutzer-Avatar
GolezTrol

Da ein Hex-Farbcode auch aus 3 Zeichen bestehen kann, kann man eine obligatorische Gruppe und eine optionale Gruppe aus Buchstaben und Ziffern definieren, die lange und aufwendige Schreibweise wäre also:

/#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\b/

Oder wenn Sie eine nette und kurze Version wollen, können Sie sagen, dass Sie entweder 1 oder 2 Gruppen von 3 alphanumerischen Zeichen wollen und dass sie ohne Berücksichtigung der Groß-/Kleinschreibung übereinstimmen sollten (/i).

/#([a-f0-9]{3}){1,2}\b/i

Anstatt von [a-f0-9] du kannst auch schreiben [[:xdigit:]], wenn die Regex-Engine diese Posix-Zeichenklasse unterstützt. In diesem Fall können Sie das überspringen /i am Ende, und die ganze Formel ist nur zwei Zeichen mehr, aber wohl aussagekräftiger.

/#([[:xdigit:]]{3}){1,2}\b/

  • Danke, \b ist das, was benötigt wurde. Nicht sicher, warum es “?” obwohl. Wie auch immer, das funktioniert nach Bedarf: /#(?:[0-9a-fA-F]{6})\b/ Vergessen zu erwähnen, dass 3-Zeichen-Codes nicht benötigt werden.

    – Hämaul

    11. Oktober 2012 um 11:07 Uhr

  • Ein Fragezeichen erfordert null oder ein Vorkommen des vorhergehenden, sodass die zweite erfasste Gruppe optional ist.

    – Asad Saeeduddin

    11. Oktober 2012 um 11:41 Uhr

  • Diese Wechsel sind sinnlos. Hier ist eine einfachere Version: /#([a-fA-F0-9]){3}(([a-fA-F0-9]){3})?\b/

    – Synchron

    27. November 2013 um 14:06 Uhr

  • @HamZa Danke, kein Problem. Eigentlich haben sich meine Regex-Fähigkeiten nicht sehr verbessert, da ich sie spärlich verwende. Ein Grund dafür ist die schlechte Lesbarkeit. Ich bin zufrieden mit dem, das ich geschrieben habe, weil es sehr gut lesbar ist, auch wenn es etwas überflüssig ist. Genau wie bei “normalem” Code denke ich, dass kürzer nicht unbedingt besser ist. Ich hätte Ihre Version jedoch verlassen, wenn sie eher eine Ergänzung als ein vollständiger Ersatz meiner Antwort gewesen wäre.

    – GolezTrol

    5. August 2014 um 15:02 Uhr


  • @evolross Gleicht Farbcodes in einer Zeichenfolge ab. Es wird mit dem übereinstimmen #FFF in #FFF#FF, aber nicht der letzte Teil. Wenn Sie die exakte Zeichenfolge finden möchten, können Sie der Regex „Anker“ für die Zeichenfolgenbegrenzung hinzufügen, sodass sie so etwas wie ^#([a-f0-9]{3}){1,2}\b$. Sehen https://regex101.com/r/LZJr63/1 für einen Zusammenbruch.

    – GolezTrol

    26. Oktober 2018 um 2:59 Uhr


Die akzeptierte Antwort zeigt Ihnen, wie Sie es mit Regex machen, denn das war Ihre Frage. Aber Sie brauchen dafür wirklich keinen regulären Ausdruck zu verwenden. Normalerweise würde ich es so machen:

if(ctype_xdigit($color) && strlen($color)==6){
    // yay, it's a hex color!
}

für 100.000 Iterationen:

Regex-Lösung *: 0,0802619457245 Sekunden

Xdigit mit strlen: 0,0277080535889 Sekunden

*: hex: ([a-fA-F0-9]{6})

  • Wer ruft diese Funktion 100.000 Mal auf?

    – nkolaw

    29. April 2017 um 23:34 Uhr

  • Tut mir leid, aber solche Dinge sind verrückt. Diese Funktion wird in einer gegebenen PHP-Datei höchstens fünfmal wie heißen? Wir reden also von einem Bruchteil einer Millisekunde?

    – nkolaw

    2. Mai 2017 um 20:16 Uhr

  • Diese Antwort verdient viel mehr Upvotes. Die Codes sind nicht nur dreimal schneller, sondern auch kürzer und einfacher zu verstehen.

    – Dan Bray

    1. November 2017 um 21:13 Uhr

  • aber ich möchte mit # nachfragen, würden Sie mir bitte helfen

    – Sachin Sarola

    24. Mai 2018 um 5:15 Uhr

  • Auf jeden Fall verdient diese Antwort viel mehr Upvotes. Funktionen sind in Zukunft viel einfacher zu verstehen und zu unterstützen als Regex.

    – alexey-novikov

    11. September 2019 um 11:02 Uhr

Benutzer-Avatar
Rotkehlchen

Kürzere Version von GolezTrols Antwort, die das zweimalige Schreiben des Zeichensatzes vermeidet:

/#([a-fA-F0-9]{3}){1,2}\b/

  • Sie können es sogar kurz machen, indem Sie die verwenden i Übereinstimmungs-Flag ohne Berücksichtigung der Groß-/Kleinschreibung. /#([a-f0-9]{3}){1,2}\b/i

    – Tuschar

    10. Februar 2016 um 14:33 Uhr

Benutzer-Avatar
Beere M.

Trotz des Alters dieser Frage möchte ich Folgendes ändern:

^#([[:xdigit:]]{3}){1,2}$wo [[:xdigit:]] ist eine Abkürzung für [a-fA-F0-9].

So:
<?php preg_match_all("/^#(?>[[:xdigit:]]{3}){1,2}$/", $css, $matches) ?>

Bemerkenswert ist hier auch die Verwendung einer nicht einfangenden Gruppe (?>...)um sicherzustellen, dass wir keine Daten im Speicher speichern, die wir eigentlich nie speichern wollten.

Probieren Sie es online aus

Benutzer-Avatar
Elias Van Ootegem

Ich bin mir nicht ganz sicher, ob ich das richtig verstanden habe, aber wenn Sie nur Hex-Farben am Ende einer CSS-Zeile abgleichen möchten:

preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);

funktionieren sollte, habe ich lediglich das optionale hinzugefügt \s; Zeichengruppe (optional Semikolon und Leerzeichen) und ein Zeilenumbruchzeichen (nicht optional) und es schien zu funktionieren.
Und wie @GolezTrol betonte #FFF; gilt auch.

Wenn darauf getestet:

$css="/* Do not match me: #abcdefgh; I am longer than needed. */
.foo
{
    color: #CAB;
    background-color:#ababab;
}";
preg_match_all('/#(?:[0-9a-fA-F]{6}|[0-9a-fA-F]{3})[\s;]*\n/',$css,$matches);
var_dump($matches);

Die Ausgabe war:

array (array('#CAB;','#ababab;'))

1215380cookie-checkRegex für passende CSS-Hex-Farben

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy