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);
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
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:
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
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
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.
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;'))
12153800cookie-checkRegex für passende CSS-Hex-Farbenyes
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