841 Stimmen

Strings in Wörter mit mehreren Wortbegrenzern aufteilen

Ich denke, was ich tun möchte, ist eine ziemlich häufige Aufgabe, aber ich habe keine Referenz im Web gefunden. Ich habe Text mit Satzzeichen und möchte eine Liste der Wörter.

"Hey, you - what are you doing here!?"

sollte sein

['hey', 'you', 'what', 'are', 'you', 'doing', 'here']

Aber Pythons str.split() funktioniert nur mit einem Argument, also habe ich alle Wörter mit dem Satzzeichen, nachdem ich mit Leerzeichen aufgeteilt habe. Irgendwelche Ideen?

7 Stimmen

13 Stimmen

Python's str.split() funktioniert auch ohne Argumente überhaupt

2voto

cosmicFluke Punkte 346

Zunächst einmal glaube ich nicht, dass Ihre Absicht tatsächlich darin besteht, Satzzeichen als Trennzeichen in den Split-Funktionen zu verwenden. Ihre Beschreibung legt nahe, dass Sie einfach die Satzzeichen aus den resultierenden Zeichenfolgen entfernen möchten.

Dies begegnet mir ziemlich häufig, und meine übliche Lösung erfordert keinen erneuten Import.

Einzeilige Lambda-Funktion mit Listenverständnis:

(erfordert import string):

split_without_punc = lambda text : [word.strip(string.punctuation) for word in 
    text.split() if word.strip(string.punctuation) != '']

# Funktionsaufruf
split_without_punc("Hey, you -- what are you doing?!")
# gibt ['Hey', 'you', 'what', 'are', 'you', 'doing'] zurück

Funktion (traditionell)

Als traditionelle Funktion sind dies immer noch nur zwei Zeilen mit einer Listenverständnis (zusätzlich zu import string):

def split_without_punctuation2(text):

    # Nach Leerzeichen aufteilen
    Worte = text.split()

    # Satzzeichen von jedem Wort entfernen
    return [word.strip(ignore) for word in words if word.strip(ignore) != '']

split_without_punctuation2("Hey, you -- what are you doing?!")
# gibt ['Hey', 'you', 'what', 'are', 'you', 'doing'] zurück

Es lässt auch natürlich Kontraktionen und Bindestriche intakt. Sie können jederzeit text.replace("-", " ") verwenden, um Bindestriche in Leerzeichen umzuwandeln, bevor Sie aufteilen.

Allgemeine Funktion ohne Lambda oder Listenverständnis

Für eine allgemeinere Lösung (bei der Sie die Zeichen angeben können, die entfernt werden sollen) und ohne Listenverständnis erhalten Sie:

def split_without(text: str, ignore: str) -> list:

    # Nach Leerzeichen aufteilen
    split_string = text.split()

    # Satzzeichen aus dem Ignore-String entfernen und leere Zeichenfolgen ignorieren
    Worte = []
    for word in split_string:
        word = word.strip(ignore)
        if word != '':
            words.append(word)

    return words

# Situationsspezifischer Aufruf der allgemeinen Funktion
import string
final_text = split_without("Hey, you - what are you doing?!", string.punctuation)
# gibt ['Hey', 'you', 'what', 'are', 'you', 'doing'] zurück

Sie können die Lambda-Funktion natürlich auch auf beliebige angegebene Zeichenfolgen von Zeichen verallgemeinern.

1voto

Wood Punkte 167

Ich musste meine eigene Lösung finden, da bisher alles, was ich getestet habe, irgendwann gescheitert ist.

>>> import re
>>> def split_words(text):
...     rgx = re.compile(r"((?:(?

`Es scheint gut zu funktionieren, zumindest für die folgenden Beispiele.

>>> split_words("The hill-tops gleam in morning's spring.")
['The', 'hill-tops', 'gleam', 'in', "morning's", 'spring']
>>> split_words("I'd say it's James' 'time'.")
["I'd", 'say', "it's", "James'", 'time']
>>> split_words("tic-tac-toe's tic-tac-toe'll tic-tac'tic-tac we'll--if tic-tac")
["tic-tac-toe's", "tic-tac-toe'll", "tic-tac'tic-tac", "we'll", 'if', 'tic-tac']
>>> split_words("google.com email@google.com split_words")
['google', 'com', 'email', 'google', 'com', 'split_words']
>>> split_words("Kurt Friedrich Gödel (/rdl/;[2] German: [kt ødl] (listen);")
['Kurt', 'Friedrich', 'Gödel', 'rdl', '2', 'German', 'k', 't', 'ødl', 'listen']
>>> split_words("April 28, 1906 – January 14, 1978) was an Austro-Hungarian-born Austrian...")
['April', '28', '1906', 'January', '14', '1978', 'was', 'an', 'Austro-Hungarian-born', 'Austrian']`

1voto

Everett Punkte 6075

Ich mag die Lösung von pprzemek, weil sie nicht davon ausgeht, dass die Trennzeichen einzelne Zeichen sind und nicht versucht, ein Regex zu verwenden (was nicht gut funktionieren würde, wenn die Anzahl der Trennzeichen sehr lang würde).

Hier ist eine übersichtlichere Version der obigen Lösung:

def split_string_on_multiple_separators(input_string, separators):
    buffer = [input_string]
    for sep in separators:
        strings = buffer
        buffer = []  # den Buffer zurücksetzen
        for s in strings:
            buffer = buffer + s.split(sep)

    return buffer

1voto

user852006 Punkte 11

Erstellen Sie eine Funktion, die zwei Zeichenfolgen als Eingabe erhält (die Quellzeichenfolge, die aufgeteilt werden soll, und die Zeichenfolge der Trennzeichen) und eine Liste von aufgeteilten Wörtern ausgibt:

def split_string(source, splitlist):
    output = []  # Ausgabeliste der bereinigten Wörter
    atsplit = True
    for char in source:
        if char in splitlist:
            atsplit = True
        else:
            if atsplit:
                output.append(char)  # Neues Wort nach Aufteilung anhängen
                atsplit = False
            else: 
                output[-1] = output[-1] + char  # Fortfahren mit dem Kopieren von Zeichen bis zur nächsten Aufteilung
    return output

1voto

Tasneem Haider Punkte 191

Hier ist die Antwort mit einiger Erklärung.

st = "Hey, you - what are you doing here!?"

# ersetze alle nicht alphanumerischen Zeichen durch Leerzeichen und verbinde sie dann.
new_string = ''.join([x.replace(x, ' ') if not x.isalnum() else x for x in st])
# Ausgabe von new_string
'Hey  you  what are you doing here  '

# str.split() entfernt alle leeren Strings, wenn kein Trennzeichen angegeben ist
new_list = new_string.split()

# Ausgabe von new_list
['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']

# wir können es verbinden, um einen vollständigen String ohne nicht alphanumerische Zeichen zu erhalten
' '.join(new_list)
# Ausgabe
'Hey you what are you doing'

oder in einer Zeile können wir es so machen:

(''.join([x.replace(x, ' ') if not x.isalnum() else x for x in st])).split()

# Ausgabe
['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']

aktualisierte Antwort

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X