488 Stimmen

Mehrere Leerzeichen durch einfache Leerzeichen in Python ersetzen

Ich habe diesen String:

mystring = 'Here is  some   text   I      wrote   '

Wie kann ich die doppelten und dreifachen (...) Leerzeichen durch ein einfaches Leerzeichen ersetzen, so dass ich folgendes erhalte?

mystring = 'Here is some text I wrote'

1018voto

Alex Martelli Punkte 805329

Eine einfache Möglichkeit (wenn Sie REs lieber vermeiden möchten) ist

' '.join(mystring.split())

Split und Join führen die Aufgabe aus, nach der Sie explizit gefragt haben - und sie führen auch die zusätzliche Aufgabe aus, von der Sie nicht sprechen, die aber in Ihrem Beispiel zu sehen ist: das Entfernen von Leerzeichen am Ende;-).

196voto

hroest Punkte 1953

Ein regulärer Ausdruck kann verwendet werden, um mehr Kontrolle über die zu kombinierenden Leerzeichen zu haben.

Für die Übereinstimmung mit Unicode-Whitespace:

import re

_RE_COMBINE_WHITESPACE = re.compile(r"\s+")

my_str = _RE_COMBINE_WHITESPACE.sub(" ", my_str).strip()

Um nur ASCII-Whitespace abzugleichen:

import re

_RE_COMBINE_WHITESPACE = re.compile(r"(?a:\s+)")
_RE_STRIP_WHITESPACE = re.compile(r"(?a:^\s+|\s+$)")

my_str = _RE_COMBINE_WHITESPACE.sub(" ", my_str)
my_str = _RE_STRIP_WHITESPACE.sub("", my_str)

Nur ASCII-Whitespace abzugleichen ist manchmal unerlässlich, um Steuerzeichen wie x0b, x0c, x1c, x1d, x1e, x1f zu erhalten.

Referenz:

Über \s :

Für Unicode (str)-Muster: Passt auf Unicode-Whitespace-Zeichen (einschließlich [ \t\n\r\f\v ], aber auch viele andere Zeichen, zum Beispiel das nicht umbrechende Leerzeichen, die in vielen Sprachen durch typografische Regeln vorgeschrieben sind). Wenn das ASCII-Flag verwendet wird, werden nur [ \t\n\r\f\v ] übereinstimmt.

Über re.ASCII :

Machen Sie \w , \W , \b , \B , \d , \D , \s y \S einen reinen ASCII-Abgleich anstelle eines vollständigen Unicode-Abgleichs durchführen. Dies ist nur für Unicode-Muster sinnvoll Mustern sinnvoll und wird bei Byte-Mustern ignoriert. Entspricht dem Inline Flagge (?a).

strip() entfernt alle führenden und nachgestellten Leerzeichen.

48voto

David C Punkte 6779

Der Vollständigkeit halber können Sie auch verwenden:

mystring = mystring.strip()  # the while loop will leave a trailing space, 
                  # so the trailing whitespace must be dealt with
                  # before or after the while loop
while '  ' in mystring:
    mystring = mystring.replace('  ', ' ')

was bei Zeichenketten mit relativ wenigen Leerzeichen schnell funktioniert (schneller als re in diesen Situationen).

In jedem Szenario, Alex Martellis Split/Join-Lösung mindestens genauso schnell (in der Regel deutlich schneller) abläuft.

In Ihrem Beispiel erhalte ich bei Verwendung der Standardwerte von timeit.Timer.repeat() die folgenden Zeiten:

str.replace: [1.4317800167340238, 1.4174888149192384, 1.4163512401715934]
re.sub:      [3.741931446594549,  3.8389395858970374, 3.973777672860706]
split/join:  [0.6530919432498195, 0.6252146571700905, 0.6346594329726258]

EDITAR:

Ich bin gerade auf diese Stelle die einen recht langen Vergleich der Geschwindigkeiten dieser Methoden enthält.

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