Regulärer Ausdruck der Strings zerteilt

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
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Guten Abend,

ich brauch jetzt keine Hilfe um eine RegExe zu schreiben der Strings zerteilt, das ist die leichte Sache. Mein Problem lässt sich am einfachsten an Hand eines Beispiels verdeutlichen:

Code: Alles auswählen

for item in enumerate(split("( |,)",s)): print item
Ausgabe:
(0, 'Ein')
(1, ' ')
(2, 'String')
(3, ' ')
(4, 'ist')
(5, ',')
(6, '')
(7, ' ')
(8, 'das')
(9, ' ')
(10, 'hier')
so weit so gut nur gibt es eine Möglichkeit den Effekt bei 6 zu vermeiden? Diese None Strings stören einfach.
Dieses Beispiel ist stark vereinfacht und dient nur der Demonstration. Die eigentliche RegExe ist die hier:

Code: Alles auswählen

re.compile(r"""([\n\[\]\{\}\(\);\=\#\\\/\<\>]|     # Einzelne Zeihen
                     [ \t\v\s]+|                                # Zeichen Mengen
                     \"\"\"|\'\'\'|\"\')                        # 3 Zeichen Token
                    """, flags = DOTALL | UNICODE | VERBOSE)
Leider kann ich auf die oder "|" nicht verzichten.
Mit freundlichen Grüßen

Albertus
BlackJack

@albertus: Filter die doch einfach heraus. `itertools.ifilter()` oder `filter()` entweder mit einer entsprechenden Testfunktion oder `None` -- dann werden alle Werte verworfen, die als Wahrheitswert gesehen "falsch" sind. Und das trifft auf leere Zeichenketten ja zu.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Vielleicht sollte man den Thread auch noch ins Allgemeine Forum verschieben?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Hallo BlackJack,
BlackJack hat geschrieben:@albertus: Filter die doch einfach heraus. `itertools.ifilter()` oder `filter()`...
gute Idee die Funktioniert aber besser wehre es doch wenn man diese None Werte vermeiden könnte. Wenn es nicht geht (was ich vermute) ist das die Lösung.
Mit freundlichen Grüßen

Albertus
BlackJack

@albertus: Das geht halt nicht, sollte aber eigentlich auch logisch sein. Wenn zwischen zwei Trennern nichts steht, dann wird eben genau das zurückgegeben, was dazwischen steht.
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Hallo BlackJack,
BlackJack hat geschrieben:@albertus: Das geht halt nicht, sollte aber eigentlich auch logisch sein.
das es logisch ist sehe ich auch auch ein blöd ist es trotzdem wehre schön wenn das split von aus dem Modul (bzw, des compilatas) eine Option kennen würde der solche None werde gleich aussortiert. Dann bräuchte man das nicht selber erledigen. :D und wenn ich es mir recht überlege das ist die Frage die ich eigentlich stellen wollte die mir aber nicht einfiel :wink:
Mit freundlichen Grüßen

Albertus
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Geht 'split(r"([, ]+)", s)' besser?
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Hallo besser-wisser,
b.esser-wisser hat geschrieben:Geht 'split(r"([, ]+)", s)' besser?
Leider nur bedingt. Wie aus dem Anfangsposting hervor geht, brauche ich die Alternativen, den 3 Anführungszeichen:

Code: Alles auswählen

\"\"\"|\'\'\'|\"\'
sind auch ein Kriterium an dem split "zuschlagen" soll. Das gleiche gilt für Leerraum:

Code: Alles auswählen

[ \t\v\s]+
beliebiger Länge. Die anderen Zeichen:

Code: Alles auswählen

[\n\[\]\{\}\(\);\=\#\\\/\<\>] 
kommen dagegen nur einmal vor bzw. selten gehäuft. Somit funktioniert deine Lösung leider nicht, den sie bildet eine Zeichenmenge, aus der ein Zeichen passen muss. Somit würde das:

Code: Alles auswählen

s ='Ein String """ist""", das hier'
zu das:

Code: Alles auswählen

['Ein', ' ', 'String', ' ', '', '"', '', '"', '', '"', 'ist', '"', '', '"', '', '"', ',', ' ', 'das', ' ', 'hier']
was mir nicht viel bringt.
Mit freundlichen Grüßen

Albertus
Benutzeravatar
b.esser-wisser
User
Beiträge: 272
Registriert: Freitag 20. Februar 2009, 14:21
Wohnort: Bundeshauptstadt B.

Dann ist filter() die einfachere/lesbarere Lösung.
Ich weise noch auf 'shlex.split()' hin - das Unterstützt aber kein Unicode, und ich habe keine Ahnung wie/ob das unter Python 3 funktioniert.

Und mach mal halblang mit den backslash's :o

Code: Alles auswählen

re.compile(r"""
    (
    [][{}();=\#\\/<>]  |  # ']' als erstes, '\' und '#' escaped
    \s+                |  # '\s' deckt alle whitespace's ab (auch \n)
                          # (gibt viel davon im unicode)
    "{3}|'{3}          |  # Drei " kollidieren mit der string-literal-markierung
    "'                    # einzelne Anfuehrungszeichen
    )""",
    flags = DOTALL | UNICODE | VERBOSE)
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Guten Morgen besser-wisser
b.esser-wisser hat geschrieben:Ich weise noch auf 'shlex.split()' hin - das Unterstützt aber kein Unicode, und ich habe keine Ahnung wie/ob das unter Python 3 funktioniert.
Dann scheidet 'shlex.split()' aus, unicode ist flicht.
b.esser-wisser hat geschrieben: Und mach mal halblang mit den backslash's :o
Warum denn sieht doch soooo schön aus :D Nein im ernst es waren definitiv zu viel backslash's das schmerzt in den Augen,

Code: Alles auswählen

re.compile(r"""
    (
    \s+                |  # '\s' deckt alle whitespace's ab (auch \n)
    )""",
    flags = DOTALL | UNICODE | VERBOSE)
Das geht leider nicht, ich brauche den '\n' ohne die anderen Leerzeichen. Deshalb wurde er separat in der ersten Alternative aufgeführt und die Zeichenklasse \s scheidet somit aus (oder?)
Mit freundlichen Grüßen

Albertus
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

albertus hat geschrieben:Guten Morgen besser-wisser
b.esser-wisser hat geschrieben:Ich weise noch auf 'shlex.split()' hin - das Unterstützt aber kein Unicode, und ich habe keine Ahnung wie/ob das unter Python 3 funktioniert.
Dann scheidet 'shlex.split()' aus, unicode ist flicht.
Du kannst den Text ja in utf-8 wandeln und später die Zeichen / Token zurück in Unicode. utf-8 deckt doch den gesamten Unicode-Raum vollständig ab.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
albertus
User
Beiträge: 52
Registriert: Mittwoch 7. Juli 2010, 14:48

Hyperion hat geschrieben:
albertus hat geschrieben:Guten Morgen besser-wisser
b.esser-wisser hat geschrieben:Ich weise noch auf 'shlex.split()' hin - das Unterstützt aber kein Unicode, und ich habe keine Ahnung wie/ob das unter Python 3 funktioniert.
Dann scheidet 'shlex.split()' aus, unicode ist flicht.
Du kannst den Text ja in utf-8 wandeln und später die Zeichen / Token zurück in Unicode. utf-8 deckt doch den gesamten Unicode-Raum vollständig ab.
So, habe mir das Modul shlex angeschaut, muss aber sagen, das es meinen Ansprüchen nicht gerecht wird. Split aus dem Modul shlex kann tatsächlich nicht mit Unicode umgehen. Das wehre nicht so schlimm, den wie du vorgeschlagen hast, kann das unicode Objekt vorher in utf8 umgewandelt werden. Das KO Kriterium ist die Tatsache, das split nicht genau dort zerteilt wo ich es gerne hätte. Ich müsste also den ganzen Code, den ich schon fertig habe, noch mal überarbeiten ohne dabei ein mehr wert zu haben.
Mit freundlichen Grüßen

Albertus
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

albertus hat geschrieben: Das wehre nicht so schlimm, den wie du vorgeschlagen hast, ...
"wäre", sorry stach mir jetzt schon so oft ins Auge :D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten