String aufbröseln...

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.
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Mittwoch 9. Juli 2008, 15:31

Karl hat geschrieben:EnTeQuAk: Deine Lösung kann aber zum Beispiel nicht mit einem = in einem String umgehen, weil dann ein SyntaxError kommen müsste.
Außerdem wird ja immer gegen eval gepredigt :)
Stimmt, das hier geht aber:

Code: Alles auswählen


def split(s):
    keys = [k for k in s if s[s.index(k)+1]=='=']
    for i, item in enumerate(s):
        if item == '=':
            key = s[i-1]
            if not key in keys:
                continue
            last_key = keys[-1] == key
            if last_key:
                value = s[i+1:]
            else:
                value = s[i+1:s.index(keys[keys.index(key)+1])-1]
            yield key, value

def main():
    ts = u'a=1 b="X =Y Z" c=True d=None'
    print dict((k, eval(v)) for k,v in split(ts))

if __name__ == '__main__':
    main()
Ansonsten sieht Masaru's Lösung auch nicht schlecht aus :D


€dit: Mist, geht auch nicht. Wenn X=Y im `b` value steht, gehts auch nicht. Vergesst die Lösung :D
Kurt Z
User
Beiträge: 23
Registriert: Samstag 17. Mai 2008, 17:43

Mittwoch 9. Juli 2008, 15:47

Frage: Wie parse ich mit Shlex einen String an der sowohl ' als auch " enthält ? Bzw. wie escape ich Quotes?
BlackJack

Mittwoch 9. Juli 2008, 15:50

@Kurt Z: Mit einem Backslash.
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Mittwoch 9. Juli 2008, 15:53

Hi Masaru,
Masaru hat geschrieben:@Karl: Hier wäre dann das Problem mit einem '=' im String wieder ausgehebelt ;).
Und was ist mit nicht-\w-Zeichen wie [.,;:], Klammern, usw.?

Jens hat bislang noch nicht behauptet (oder ich habe es überlesen), dass es sich um Programmcode oder sogar Python-Code handelt.

Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Mittwoch 9. Juli 2008, 15:54

Huch, hab den Seiten-Wechsel gar nicht mitbekommen beim editieren.

Naja, hier mal eine gaaanz kurze Variante

Code: Alles auswählen

import re 
s = u'a=1 b="X=Y=Z" c=True d=None'
r = dict([ (t[0], eval(t[1])) for t in [ h.split('=', 1) for h in re.findall('(\w*=".*"|\w*=\w*)', s) ]])
>>Masaru<<
Kurt Z
User
Beiträge: 23
Registriert: Samstag 17. Mai 2008, 17:43

Mittwoch 9. Juli 2008, 16:02

BlackJack hat geschrieben:@Kurt Z: Mit einem Backslash.
wie genau ???

Code: Alles auswählen

>>> shlex.split("""a=1 b='X \' Y Z' c=True d='test' e=None""")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.3/shlex.py", line 279, in split
    return list(lex)
  File "/usr/lib/python2.3/shlex.py", line 269, in next
    token = self.get_token()
  File "/usr/lib/python2.3/shlex.py", line 96, in get_token
    raw = self.read_token()
  File "/usr/lib/python2.3/shlex.py", line 172, in read_token
    raise ValueError, "No closing quotation"
ValueError: No closing quotation
BlackJack

Mittwoch 9. Juli 2008, 16:09

@Kurt Z: Ganz einfach mit einem Backslash vor dem entsprechenden Quote. Kleiner Tipp: Du hast da keins weil '\' in Python-Zeichenketten ja auch eine Bedeutung haben.

Code: Alles auswählen

In [101]: print '''foo="X \'Y\' Z"'''
foo="X 'Y' Z"

In [102]: print '''foo="X \\'Y\\' Z"'''
foo="X \'Y\' Z"
Kurt Z
User
Beiträge: 23
Registriert: Samstag 17. Mai 2008, 17:43

Mittwoch 9. Juli 2008, 16:16

BlackJack hat geschrieben:@Kurt Z: Ganz einfach mit einem Backslash vor dem entsprechenden Quote. Kleiner Tipp: Du hast da keins weil '\' in Python-Zeichenketten ja auch eine Bedeutung haben.
m.a.W. es geht, aber Python-Code darf nicht die Quelle sein?

Code: Alles auswählen

>>> shlex.split("""a=1 b='X \\' Y Z' c=True d='test' e=None""")
Traceback (most recent call last):
 ...
ValueError: No closing quotation
>>> shlex.split("""a=1 b='X \\\' Y Z' c=True d='test' e=None""")
Traceback (most recent call last):
...
ValueError: No closing quotation
ich kann kein Python bitte zeigts mir...
Kurt Z
User
Beiträge: 23
Registriert: Samstag 17. Mai 2008, 17:43

Mittwoch 9. Juli 2008, 16:41

ok so gehts ...

Code: Alles auswählen

>>> shlex.split('a=1 b=" \' \\\" " c=True d="test" e=None')
['a=1', 'b= \' " ', 'c=True', 'd=test', 'e=None']

>>> shlex.split("a=1 b=\" \\\" ' \" c=True d='test' e=None")
['a=1', 'b= " \' ', 'c=True', 'd=test', 'e=None']
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 9. Juli 2008, 17:18

shlex sieht wirklich gut aus! Sehe ich jetzt zum ersten mal... Danke an alle ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 10. Juli 2008, 13:22

Meine Lösung:

Code: Alles auswählen

def make_kwagrs(raw_content):
    """
    convert a string into a dictionary. e.g.:
    
    >>> make_kwagrs('key1="value1" key2="value2"')
    {'key2': 'value2', 'key1': 'value1'}
   
    >>> make_kwagrs('A="B" C=1 D=1.1 E=True F=False G=None')
    {'A': 'B', 'C': 1, 'E': True, 'D': '1.1', 'G': None, 'F': False}
    """
    parts = shlex.split(raw_content)

    result = {}
    for part in parts:
        key, value = part.split("=", 1)
        
        if value in KEYWORD_MAP:
            # True False or None
            value = KEYWORD_MAP[value]
        else:
            # A number?
            try:
                value = int(value)
            except ValueError:
                pass 
                                   
        result[key] = value

    return result
btw. doofes DocTest, siehe: doctest und dict (Key Reihenfolge)

EDIT: Ach, dumm... shlex.split() macht ärger bei unicode:

Code: Alles auswählen

>>> repr(shlex.split(u"A=1 B=2"))
['A\x00\x00\x00=\x00\x00\x001\x00\x00\x00', '\x00\x00\x00B\x00\x00\x00=\x00\x00\x002\x00\x00\x00']

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 10. Juli 2008, 15:02

Ah ich sehe gerade:
Note: The shlex module currently does not support Unicode input.
[mod]shlex[/mod]

Ja, dann... :?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Donnerstag 10. Juli 2008, 15:04

Irgendwo muss doch die Herausforderung sein, also los, mach dich ran ;)
Kurt Z
User
Beiträge: 23
Registriert: Samstag 17. Mai 2008, 17:43

Donnerstag 10. Juli 2008, 15:40

jens hat geschrieben:Ah ich sehe gerade:
Note: The shlex module currently does not support Unicode input.
[mod]shlex[/mod]

Ja, dann... :?
hmm ...solange du die Grammatik nicht präzisierst, ist jede weitere RegEx Diskussiion sowieso hinfällig...

Kommen in strings quotes vor ?
sowohl ' als auch " ?
Wie soll dann escaped werden ?
Benutzeravatar
Masaru
User
Beiträge: 425
Registriert: Mittwoch 4. August 2004, 22:17

Donnerstag 10. Juli 2008, 15:44

Kurt Z hat geschrieben:...Kommen in strings quotes vor ?
sowohl ' als auch " ?
Wie soll dann escaped werden ?
So :)

Code: Alles auswählen

>>> print '\''
'
>>> print """
"
Antworten