Seite 1 von 1

Regex aus Strings und Variablen zusammensetzen

Verfasst: Samstag 10. März 2007, 01:48
von PmanX
Hallo,

habe meinen Lieblingsregex(CSV) in Python umgesetzt.

Code: Alles auswählen

import re

my_str = r''',22,"ffff","ee\eee","rtt,22z",221,,"g",'''

my_cre = re.compile(r'''
                 "([^"\\]*(?:\\.[^"\\]*)*)",?  # String in Anfuehrungszeichen(Komma erlaubt)
                | ([^,]+),?                        # ohne Anfuehrungszeichen(meist Ziffern)
                | ,                                    # oder nur ein Komma
                        ''',re.VERBOSE)

my_iter = my_cre.finditer(my_str)

my_list = []

for m in my_iter:
    if m.group(1): my_list.append(m.group(1))
    else:               my_list.append(m.group(2))

    
print my_list

[None, '22', 'ffff', 'ee\\eee', 'rtt,22z', '221', None, 'g']
Die Regex nehme ich auch gern für split. Habt Ihr eine Idee, wie ich das Komma gegen Semikolon oä. austauschen kann?

Gruß P.

Verfasst: Samstag 10. März 2007, 02:05
von Costi
hmmm
ich bin mir nicht sicher ob ich dein problem richtig verstanden habe, aber wie waers mit: 'a, str'.replace(',', ';')

Re: Regex aus Strings und Variablen zusammensetzen

Verfasst: Samstag 10. März 2007, 08:30
von sape
PmanX hat geschrieben:Habt Ihr eine Idee, wie ich das Komma gegen Semikolon oä. austauschen kann?

Code: Alles auswählen

...
my_str = r''',22,"ffff","ee\eee","rtt,22z",221,,"g",123;456;"789:101112"'''

my_cre = re.compile(r'''
                ...
                | ([^,;]+),? # Einfach das ; mit hinzufügen.
                ...
''')

...   
print my_list
# [None, '22', 'ffff', 'ee\\eee', 'rtt,22z', '221', None, 'g', '123', '456', '789:101112']
BTW: Nur kurz getestet!

Verfasst: Samstag 10. März 2007, 11:35
von BlackJack

Code: Alles auswählen

import csv

Verfasst: Samstag 10. März 2007, 13:27
von PmanX
Hallo,
Costi hat geschrieben:hmmm
ich bin mir nicht sicher ob ich dein problem richtig verstanden habe, aber wie waers mit: 'a, str'.replace(',', ';')
Meine ersten Versuche sehen gut aus, danke.

Edit:

Code: Alles auswählen

re_str = r'''"([^"\\]*(?:\\.[^"\\]*)*)"~?|([^~]+)~?|~'''
#my_cre = re.compile(re_str.replace('~', trennstring))
my_cre = re.compile(re_str.replace('~', trennzeichen))
Gruß P.

Verfasst: Samstag 10. März 2007, 13:46
von BlackJack
Man könnte auch Zeichenkettenformatierung benutzen:

Code: Alles auswählen

    template = (r'"([^"\\]*(?:\\.[^"\\]*)*)"%(delim)s?'
                r'|([^%(delim)s]+)%(delim)s?|%(delim)s')

    my_cre = re.compile(template % {'delim': re.escape(trennstring)})
Und das Trennzeichen "escapen", für den Fall dass es eines ist, was in regulären Ausdrücken eine besondere Bedeutung hat.

Verfasst: Samstag 10. März 2007, 14:11
von PmanX
TMTOWTDI. Guter Hinweis auf re.escape(trennzeichen).
Sehr direkt und klar :!:

EDIT: Wer's mal braucht.

Code: Alles auswählen

def my_split(zeile, trennzeichen = ','):
    tmplate = (r'"([^"\\]*(?:\\.[^"\\]*)*)"%(d)s?|([^%(d)s]+)%(d)s?|%(d)s')
    my_creg = re.compile(tmplate % {'d' : re.escape(trennzeichen)})
    my_iter = my_creg.finditer(zeile)
    my_list = []
    for i in my_iter:
        if i.group(1): my_list.append(i.group(1))
        else:          my_list.append(i.group(2))
    return my_list

Verfasst: Samstag 10. März 2007, 21:44
von EyDu
Man möge sich streiten, wie vernünftig die folgende Lösung ist, aber das fiel mir irgendwie so ins Auge:

Aus

Code: Alles auswählen

my_iter = my_creg.finditer(zeile)
my_list = []
for i in my_iter:
    if i.group(1): my_list.append(i.group(1))
    else:          my_list.append(i.group(2))
return my_list
könnte man wunderschön folgendes machen:

Code: Alles auswählen

return [i.group(1) or i.group(2) for i in my_creg.finditer(zeile)]
Und JA: Ich hab sonst kein Leben :D