RE für CSS Werte...

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Bisher habe ich re.compile(r'#([a-fA-F0-9]{3,6})') verwendet um CSS Farbwerte zu finden.
Aber eigentlich gibt es nur Farbwerte mit 3 *oder* 6 zwichen länge und nicht 3 bis 6 Zeichen (mal abgesehen von Farbnamen)...

Weiß jemand wie ich die Re verbessern kann?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jens hat geschrieben:Bisher habe ich re.compile(r'#([a-fA-F0-9]{3,6})') verwendet um CSS Farbwerte zu finden.
Aber eigentlich gibt es nur Farbwerte mit 3 *oder* 6 zwichen länge und nicht 3 bis 6 Zeichen (mal abgesehen von Farbnamen)...

Weiß jemand wie ich die Re verbessern kann?
re.compile(r'#([a-f0-9]{3}|[a-f0-9]{6})', re.IGNORECASE)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das funktioniert nicht ganz richtig, wenn z.B. die Farbe eine falsche Länge zwischen 4 bis 5 Zeichen hat. Denn dann matched {3} auf die ersten drei Zeichen.

Man müßte das Ende angeben, das es nicht [a-f0-9] sein darf.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Wenn du auch falsche Werte abdecken willst, nimm einfach:

Code: Alles auswählen

r"#([a-fA-F0-9]+)"
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

@Darii: Nein, das möchte ich eigentlich nicht...

Ich mache nun was anderes (vor dem extrahieren):

Code: Alles auswählen

import re

txt = """.foo { color: #123456; }
.bar1 { color: #abc; }
.bar2 { color: #83F ; }
"""

CSS_RE = re.compile(r'# *([a-f0-9])([a-f0-9])([a-f0-9]) *;', re.IGNORECASE)

print CSS_RE.sub("#\g<1>\g<1>\g<2>\g<2>\g<3>\g<3>;", txt)
Also konvertieren von 3 stellige Werte in 6 stellige.

EDIT: Neue RE, damit "#" am Anfang und ";" am Ende auch bleiben ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

jens hat geschrieben:Das funktioniert nicht ganz richtig, wenn z.B. die Farbe eine falsche Länge zwischen 4 bis 5 Zeichen hat. Denn dann matched {3} auf die ersten drei Zeichen.

Man müßte das Ende angeben, das es nicht [a-f0-9] sein darf.
Eigentlich darf das Ende gar nichts alphanumerisches sein. Damit bekommst du:

re.compile(r'#([a-f0-9]{3}[a-f0-9]{3}?)\W', re.IGNORECASE)
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Dafür ist doch lookahead da: r'#([a-fA-F0-9]{3}){1,2}(?!\w)'
Bottle: Micro Web Framework + Development Blog
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich ende lieber mit " *;" also beliebige Leerzeichen und dann ein Semikolon...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

jens hat geschrieben:Ich ende lieber mit " *;" also beliebige Leerzeichen und dann ein Semikolon...
Was im Gegensatz zu defnulls negativem Lookahead aber nicht alle Fälle abdeckt. Habt ihr übrigens bedacht, dass die Alternative "erst drei, dann sechs Zeichen" zuerst den kleineren findet? Besser ist es, das umzudrehen, und zuerst auf 6 Zeichen und dann auf 3 Zeichen zu prüfen.

Korrekt gemäß CSS ist das alles natürlich nicht, denn ein "content: '#fff'" würde fälschlich als Farbe und nicht als String erkannt werden. Auch in der CSS-Datei enthaltene Kommentare können natürlich #FFF o.ä. enthalten. Nicht erkannt werden natürlich Farbdefinitionen mittels "rgb()".

Stefan
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

sma hat geschrieben:Habt ihr übrigens bedacht, dass die Alternative "erst drei, dann sechs Zeichen" zuerst den kleineren findet? Besser ist es, das umzudrehen, und zuerst auf 6 Zeichen und dann auf 3 Zeichen zu prüfen.
Jaja, die Lösung mit der Alternative war ohnehin Mist und ist ziemlich schnell rausgeflogen.
Antworten