2009-11-30 16 views
17
behält

Gibt es eine Entsprechung zu str.split in Python, die auch die Trennzeichen zurückgibt?Tokenize eine Zeichenfolge, die Trennzeichen in Python

Ich muss das Leerzeichen Layout für meine Ausgabe nach der Verarbeitung einiger der Token beibehalten.

Beispiel:

>>> s="\tthis is an example" 
>>> print s.split() 
['this', 'is', 'an', 'example'] 

>>> print what_I_want(s) 
['\t', 'this', ' ', 'is', ' ', 'an', ' ', 'example'] 

Dank!

+1

+1 - Interessante Frage, 'splitlines' einen' keepends' Parameter zu haben scheint, aber nicht so etwas für 'split'. Scheint seltsam (http://docs.python.org/library/stdtypes.html#str.splitlines). –

Antwort

19

Wie wäre es

import re 
splitter = re.compile(r'(\s+|\S+)') 
splitter.findall(s) 
+0

elegant und leicht erweiterbar (think '(\ s + | \ w + | \ S +)'). – hop

6
>>> re.compile(r'(\s+)').split("\tthis is an example") 
['', '\t', 'this', ' ', 'is', ' ', 'an', ' ', 'example'] 
4

die re Modul diese Funktionalität bereitstellt:

>>> import re 
>>> re.split('(\W+)', 'Words, words, words.') 
['Words', ', ', 'words', ', ', 'words', '.', ''] 

(zitiert aus der Python-Dokumentation).

Für Ihr Beispiel (Auf Leerzeichen aufgeteilt) verwenden Sie re.split('(\s+)', '\tThis is an example').

Der Schlüssel ist, die Regex zu umschließen, auf die in auffangenden Klammern aufgeteilt werden soll. Auf diese Weise werden die Trennzeichen der Liste der Ergebnisse hinzugefügt.

Edit: Wie bereits erwähnt, werden natürlich auch alle vorangestellten/nachfolgenden Delimiter zur Liste hinzugefügt. Um dies zu vermeiden, können Sie zuerst die Methode .strip() für Ihre Eingabezeichenfolge verwenden.

+0

nicht die OP-Zeichenfolge Masken die Tatsache, dass die leere Zeichenfolge als das erste Element der zurückgegebenen Liste enthalten ist. – hop

+0

Danke. Ich habe meinen Beitrag dementsprechend bearbeitet (obwohl in diesem Fall die Spezifikationen des OP ("wollen Leerzeichen beibehalten") und sein Beispiel widersprüchlich waren). –

+0

Nein, es war nicht ... es gab ein Beispiel für das aktuelle Verhalten und ein anderes für das gewünschte Verhalten. – fortran

-1

Danke Jungs für den Hinweis für das re Modul, versuche ich immer noch zwischen diesem und mit meinem eigenen Funktion, um zu entscheiden, die eine Sequenz zurückgibt ...

def split_keep_delimiters(s, delims="\t\n\r "): 
    delim_group = s[0] in delims 
    start = 0 
    for index, char in enumerate(s): 
     if delim_group != (char in delims): 
      delim_group ^= True 
      yield s[start:index] 
      start = index 
    yield s[start:index+1] 

Wenn ich Zeit hätte, würde ich sie Benchmark xD

+0

keine Notwendigkeit Regex oder Erstellen Sie Ihre eigenen Räder, wenn Sie Python 2.5 weiter .. siehe meine Antwort. – ghostdog74

3

Haben Sie auf Pyapsing geschaut? Beispiel aus the pyparsing wiki entlehnt:

>>> from pyparsing import Word, alphas 
>>> greet = Word(alphas) + "," + Word(alphas) + "!" 
>>> hello1 = 'Hello, World!' 
>>> hello2 = 'Greetings, Earthlings!' 
>>> for hello in hello1, hello2: 
...  print (u'%s \u2192 %r' % (hello, greet.parseString(hello))).encode('utf-8') 
... 
Hello, World! → (['Hello', ',', 'World', '!'], {}) 
Greetings, Earthlings! → (['Greetings', ',', 'Earthlings', '!'], {}) 
Verwandte Themen