Seite 1 von 1
String auseinander stückeln
Verfasst: Samstag 31. Januar 2009, 19:27
von kromonos
Gibt es eine möglichkeit, wie ich einen String mit folgendem Inhalt in einem Array ablegen kann:
":Kromonos!
Kromonos@user-helfen-usern.de PRIVMSG #test :Dies ist eine Testnachricht"
So, dass der Array wie folgt aussehen würde:
Array = ['Kromonos','
kromonos@user-helfen-usern.de','PRIVMSG','#test','Dies ist eine Testnachricht']
Ein einfaches split() würde nicht funktionieren, da dann die komplette nachricht auseinander genommen würde -.-
Verfasst: Samstag 31. Januar 2009, 19:40
von BlackJack
Dann nimm halt keine einfachen `split()`\s sondern überlege woran man noch splitten kann. Das muss man nicht alles in einem Schritt tun, und die `str.split()`-Methode hat auch noch andere Argumente als die Zeichen an denen die Zeichenkette zerlegt werden soll.
Dazu müsstest Du wissen welche Teile der Zeichenkette fest sind und welche Variabel. An diesem einen Beispiel kann man jetzt keinen Vorschlag machen, der bei jeder Zeichenkette funktioniert.
Verfasst: Samstag 31. Januar 2009, 19:44
von Dauerbaustelle
Hallo,
das geht mit `str.split([char])`
Code: Alles auswählen
In [1]: s = ":Kromonos!Kromonos@user-helfen-usern.de PRIVMSG #test :Dies ist eine Testnachricht"
In [4]: foo, privmsg, test, msg = s.split(' ', 3) # nach Leerzeichen splitten, jedoch höchstens drei mal (weil sonst die Nachricht auch geteilt werden würde)
In [5]: foo, privmsg, test, msg
Out[5]:
(':Kromonos!Kromonos@user-helfen-usern.de',
'PRIVMSG',
'#test',
':Dies ist eine Testnachricht')
In [6]: name, mail = foo[1:].split('!')
In [7]: name, mail
Out[7]: ('Kromonos', 'Kromonos@user-helfen-usern.de')
In [8]: msg = msg[1:]
# argh, edit (`foo` statt `test` angegeben):
In [9]: name, mail, privmsg, test, msg
Out[9]:
('Kromonos',
'Kromonos@user-helfen-usern.de',
'PRIVMSG',
'#test',
'Dies ist eine Testnachricht')
achso, falls du das nicht kennst:
Code: Alles auswählen
In [10]: blah = "Hallo"
In [11]: blah[1:]
Out[11]: 'allo'
Verfasst: Samstag 31. Januar 2009, 19:48
von kromonos
BlackJack hat geschrieben:Dann nimm halt keine einfachen `split()`\s sondern überlege woran man noch splitten kann. Das muss man nicht alles in einem Schritt tun, und die `str.split()`-Methode hat auch noch andere Argumente als die Zeichen an denen die Zeichenkette zerlegt werden soll.
Dazu müsstest Du wissen welche Teile der Zeichenkette fest sind und welche Variabel. An diesem einen Beispiel kann man jetzt keinen Vorschlag machen, der bei jeder Zeichenkette funktioniert.
Es ist ein String aus dem IRC Protokoll. Fest sind die Zeichen :, ! und @
Der Beitrag von Dauerbaustelle hilft mir schon massig weiter. Vielen vielen dank

Verfasst: Samstag 31. Januar 2009, 19:58
von helduel
Moin,
das ganze wäre auch eine gute Gelegenheit, sich mit Regulären Ausdrücken auseinanderzusetzen.
Gruß,
Manuel
Verfasst: Samstag 31. Januar 2009, 20:05
von str1442
.. oder str.index + String Slicing benutzen Wenn garantiert ist, das ! nur einmal auftaucht, ungetestet:
Code: Alles auswählen
result = [string[:string.index("!")]] + string[string.index("!"):].split(" ")
Verfasst: Samstag 31. Januar 2009, 20:16
von Dauerbaustelle
Nö, wenn es zweimal auftaucht (das zweite mal nicht als Abgrenzung, sondern als Nachrichtentext), tut das auch, weil index ja immer die erste Position ausgibt.
Verfasst: Sonntag 1. Februar 2009, 00:51
von DasIch
Code: Alles auswählen
def parse_irc_message(line):
"""Parses a given irc message to prefix, command, params and trailing."""
line = line.strip()
prefix = ''
if line.startswith(':'):
prefix, line = line[1:].split(' ', 1)
trailing = ''
if ' :' in line:
line, trailing = line.split(' :', 1)
params = line.split()
command = params.pop(0).upper()
return prefix, command, params, trailing
Verfasst: Sonntag 1. Februar 2009, 09:36
von str1442
Ja, aber sollte es mehr als einmal als Abgrenzung auftauchen, wirkt eine Slice Lösung doch arg künstlich
Achja, die richtige Lösung wäre demnach:
Code: Alles auswählen
result = [string[:string.index("!")]] + string[string.index("!") + 1:].split(" ", 3)
OffbyOne. ":" zu entfernen durch Replace wäre dann das letzte.
Verfasst: Sonntag 1. Februar 2009, 12:16
von lunar
Code: Alles auswählen
>>> line = ":Kromonos!Kromonos@user-helfen-usern.de PRIVMSG #test :Dies ist eine Testnachricht"
>>> import re
>>> re.match(':(\w+)!(\w+@[a-zA-Z-.]+)\s+([A-Z]+)\s+([#a-z]+)\s+:(.+)', line).groups()
('Kromonos', 'Kromonos@user-helfen-usern.de', 'PRIVMSG', '#test', 'Dies ist eine Testnachricht')
Verfasst: Montag 2. Februar 2009, 12:40
von str1442
Es gibt auch noch re.split():
Code: Alles auswählen
>>> re.split(r"[! ]", ":Kromonos!Kromonos@user-helfen-usern.de PRIVMSG #test :Dies ist eine Testnachricht")
[':Kromonos', 'Kromonos@user-helfen-usern.de', 'PRIVMSG', '#test', ':Dies', 'ist', 'eine', 'Testnachricht']
Aber da man {<anzahl an treffern>} nicht angeben kann in den "Character Cases", funktioniert das wohl so nicht. Abgesehen von der Frage, ob es wirklich immer genau 3 Leerzeichen sind.
EDIT:
Code: Alles auswählen
>>> def f(irc_msg):
... result = re.split(r"[! ]", irc_msg)
... result[0] = result[0][1:]
... new_str = " ".join(result[4:])[1:]
... del result[4:]
... result.append(new_str)
... return result
result[4:] = " ".join(result[4:])[1:] hat komischerweise den String komplett vereinzelt
EDIT2:
Achso, ist ja eine Sequenz und wird aufgeteilt... Das hier tuts:
Code: Alles auswählen
>>> def f(irc_msg):
... result = re.split(r"[! ]", irc_msg)
... result[0] = result[0][1:]
... result[4:] = [" ".join(result[4:])[1:]]
... return result
Verfasst: Montag 2. Februar 2009, 15:02
von DasIch
str1442 hat geschrieben:Abgesehen von der Frage, ob es wirklich immer genau 3 Leerzeichen sind.
Bei PRIVMSGs schon, ansonsten natürlich nicht. Prefix und Trailing sind optional, die Anzahl der Parameter sowieso.