Wie schneide ich Leerzeichen?

1071

Gibt es eine Python-Funktion, mit der Leerzeichen (Leerzeichen und Tabulatoren) aus einer Zeichenfolge entfernt werden?

Beispiel: \t example string\texample string

Chris
quelle
1
Danke für die Warnung. Ich hatte die Strip-Funktion früher entdeckt, aber sie scheint für meine Eingabe nicht zu funktionieren.
Chris
1
Gleich wie: stackoverflow.com/questions/761804/trimming-a-string-in-python (obwohl diese Frage meiner Meinung nach etwas klarer ist). Dies ist auch fast das gleiche: stackoverflow.com/questions/959215/…
Jonik
6
Die Zeichen, die Python als Leerzeichen betrachtet, werden in gespeichert string.whitespace.
John Fouhy
2
Mit "Streifenfunktion" meinen Sie die Streifenmethode? "Es scheint nicht für meine Eingabe zu funktionieren." Bitte geben Sie Ihren Code, Ihre Eingabe und die Ausgabe an.
S.Lott
5
Mögliches Duplikat des Zuschneidens einer Zeichenfolge in Python
Breno Baiardi

Antworten:

1599

Leerzeichen auf beiden Seiten:

s = "  \t a string example\t  "
s = s.strip()

Leerzeichen auf der rechten Seite:

s = s.rstrip()

Leerzeichen auf der linken Seite:

s = s.lstrip()

Wie thedz hervorhebt , können Sie ein Argument angeben , um beliebige Zeichen für eine dieser Funktionen wie folgt zu entfernen :

s = s.strip(' \t\n\r')

Dies wird jeden Raum Streifen, \t, \n, oder \rZeichen von der linken Seite, die rechte Seite, oder auf beiden Seiten des Strings.

In den obigen Beispielen werden nur Zeichenfolgen von der linken und rechten Seite der Zeichenfolgen entfernt. Wenn Sie auch Zeichen aus der Mitte einer Zeichenfolge entfernen möchten, versuchen Sie Folgendes re.sub:

import re
print re.sub('[\s+]', '', s)

Das sollte ausdrucken:

astringexample
James Thompson
quelle
18
strip () nimmt ein Argument auf, um ihm zu sagen, was er auslösen soll. Versuchen Sie: strip ('\ t \ n \ r')
21:03 Uhr
3
Die Ergebnisse für die Beispiele sollten sehr hilfreich :) sein
ton
4
Die Whitespace-Zeichen müssen nicht
aufgelistet werden
3
Das letzte Beispiel ist genau wie mit str.replace(" ",""). Sie müssen nicht verwenden re, es sei denn, Sie haben mehr als ein Leerzeichen, dann funktioniert Ihr Beispiel nicht. []wurde entwickelt, um einzelne Zeichen zu markieren. Es ist nicht erforderlich, wenn Sie nur verwenden \s. Verwenden Sie entweder \s+oder [\s]+(nicht notwendig) , aber [\s+]die Arbeit nicht tun, insbesondere wenn man die mehrere Räume mit einem einzigen ersetzen will wie das Drehen "this example" in "this example".
Jorge E. Cardona
3
@ JorgeE.Cardona - Eine Sache, bei der Sie etwas falsch liegen - \swird Tabs enthalten, während dies replace(" ", "")nicht der Fall ist .
ArtOfWarfare
72

Die Python- trimMethode heißt strip:

str.strip() #trim
str.lstrip() #ltrim
str.rstrip() #rtrim
gcb
quelle
5
Das ist leicht zu merken, weil s tri p fast wie tri m aussieht .
Isar
22

Für führende und nachfolgende Leerzeichen:

s = '   foo    \t   '
print s.strip() # prints "foo"

Andernfalls funktioniert ein regulärer Ausdruck:

import re
pat = re.compile(r'\s+')
s = '  \t  foo   \t   bar \t  '
print pat.sub('', s) # prints "foobar"
ars
quelle
1
Sie haben Ihren regulären Ausdruck nicht kompiliert. Sie müssen es schaffenpat = re.compile(r'\s+')
Evan Fosmark
Sie wollen im Allgemeinen sub(" ", s)nicht ""die später die Worte verschmelzen und Sie werden nicht mehr nutzen können .split(" ")tokenize.
user3467349
Es wäre schön, die Ausgabe der printAussagen zu sehen
Ron Klein
19

Sie können auch eine sehr einfache und grundlegende Funktion verwenden: str.replace () , arbeitet mit den Leerzeichen und Tabulatoren:

>>> whitespaces = "   abcd ef gh ijkl       "
>>> tabs = "        abcde       fgh        ijkl"

>>> print whitespaces.replace(" ", "")
abcdefghijkl
>>> print tabs.replace(" ", "")
abcdefghijkl

Simpel und einfach.

Lucas
quelle
2
Leider wird dadurch auch der Innenraum entfernt, während das Beispiel in der ursprünglichen Frage die Innenräume unberührt lässt.
Brandon Rhodes
12
#how to trim a multi line string or a file

s=""" line one
\tline two\t
line three """

#line1 starts with a space, #2 starts and ends with a tab, #3 ends with a space.

s1=s.splitlines()
print s1
[' line one', '\tline two\t', 'line three ']

print [i.strip() for i in s1]
['line one', 'line two', 'line three']




#more details:

#we could also have used a forloop from the begining:
for line in s.splitlines():
    line=line.strip()
    process(line)

#we could also be reading a file line by line.. e.g. my_file=open(filename), or with open(filename) as myfile:
for line in my_file:
    line=line.strip()
    process(line)

#moot point: note splitlines() removed the newline characters, we can keep them by passing True:
#although split() will then remove them anyway..
s2=s.splitlines(True)
print s2
[' line one\n', '\tline two\t\n', 'line three ']
Robert King
quelle
4

Bisher hat noch niemand diese Regex-Lösungen veröffentlicht.

Matching:

>>> import re
>>> p=re.compile('\\s*(.*\\S)?\\s*')

>>> m=p.match('  \t blah ')
>>> m.group(1)
'blah'

>>> m=p.match('  \tbl ah  \t ')
>>> m.group(1)
'bl ah'

>>> m=p.match('  \t  ')
>>> print m.group(1)
None

Suchen (Sie müssen den Eingabefall "Nur Leerzeichen" unterschiedlich behandeln):

>>> p1=re.compile('\\S.*\\S')

>>> m=p1.search('  \tblah  \t ')
>>> m.group()
'blah'

>>> m=p1.search('  \tbl ah  \t ')
>>> m.group()
'bl ah'

>>> m=p1.search('  \t  ')
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

Wenn Sie verwenden re.sub, können Sie innere Leerzeichen entfernen, was unerwünscht sein kann.

user1149913
quelle
3

Whitespace enthält Leerzeichen, Tabulatoren und CRLF . Eine elegante und einzeilige String-Funktion, die wir verwenden können, ist also übersetzen .

' hello apple'.translate(None, ' \n\t\r')

ODER wenn Sie gründlich sein wollen

import string
' hello  apple'.translate(None, string.whitespace)
MaK
quelle
3

(re sub ('+', '', (my_str.replace ('\ n', ''))). strip ()

Dadurch werden alle unerwünschten Leerzeichen und Zeilenumbrüche entfernt. Ich hoffe das hilft

import re
my_str = '   a     b \n c   '
formatted_str = (re.sub(' +', ' ',(my_str.replace('\n',' ')))).strip()

Dies führt zu:

'a b \ nc' wird in 'ab c' geändert

Safvan CK
quelle
2
    something = "\t  please_     \t remove_  all_    \n\n\n\nwhitespaces\n\t  "

    something = "".join(something.split())

Ausgabe:

Please_remove_all_whitespaces


Hinzufügen des Kommentars von Le Droid zur Antwort. Mit einem Leerzeichen trennen:

    something = "\t  please     \t remove  all   extra \n\n\n\nwhitespaces\n\t  "
    something = " ".join(something.split())

Ausgabe:

Bitte entfernen Sie alle zusätzlichen Leerzeichen

pbn
quelle
1
Einfach und effizient. Könnte "" .join (... verwenden, um Wörter durch ein Leerzeichen getrennt zu halten.
Le Droid
1

Wenn Sie Python 3 verwenden: Beenden Sie in Ihrer print-Anweisung mit sep = "". Das wird alle Räume trennen.

BEISPIEL:

txt="potatoes"
print("I love ",txt,"",sep="")

Dies wird drucken: Ich liebe Kartoffeln.

Anstelle von: Ich liebe Kartoffeln.

In Ihrem Fall tun Sie sep = "\ t", da Sie versuchen würden, die \ t zu fahren.

morgansmnm
quelle
1

Nachdem ich mir hier einige Lösungen mit unterschiedlichem Verständnis angesehen hatte, fragte ich mich, was ich tun sollte, wenn die Zeichenfolge durch Kommas getrennt war ...

das Problem

Beim Versuch, eine CSV mit Kontaktinformationen zu verarbeiten, brauchte ich eine Lösung für dieses Problem: Trimmen Sie überflüssige Leerzeichen und etwas Junk, aber behalten Sie nachgestellte Kommas und interne Leerzeichen bei. Als ich mit einem Feld arbeitete, das Notizen zu den Kontakten enthielt, wollte ich den Müll entfernen und das gute Zeug zurücklassen. Nachdem ich alle Satzzeichen und Spreu entfernt hatte, wollte ich das Leerzeichen zwischen zusammengesetzten Token nicht verlieren, da ich es später nicht wieder aufbauen wollte.

Regex und Muster: [\s_]+?\W+

Das Muster sucht nach einzelnen Instanzen eines Leerzeichens und dem Unterstrich ('_') von 1 bis zu einer unbegrenzten Anzahl von Trägen (so wenig Zeichen wie möglich) [\s_]+?, bevor Nicht-Wort-Zeichen von 1 bis zu einer unbegrenzten Anzahl von Zeichen auftreten Zeit damit: \W+(entspricht [^a-zA-Z0-9_]). Insbesondere werden dabei Leerzeichen gefunden: Nullzeichen (\ 0), Tabulatoren (\ t), Zeilenumbrüche (\ n), Feed-Forward (\ f), Wagenrücklauf (\ r).

Ich sehe den Vorteil darin in zweierlei Hinsicht:

  1. dass es keine Leerzeichen zwischen den vollständigen Wörtern / Token entfernt, die Sie möglicherweise zusammenhalten möchten;

  2. Die in Python integrierte Zeichenfolgenmethode strip()behandelt nicht die Zeichenfolge, sondern nur das linke und das rechte Ende, und das Standardargument sind Nullzeichen (siehe Beispiel unten: Mehrere Zeilenumbrüche befinden sich im Text und strip()entfernen sie nicht alle, während das Regex-Muster dies tut). .text.strip(' \n\t\r')

Dies geht über die OP-Frage hinaus, aber ich denke, es gibt viele Fälle, in denen wir möglicherweise seltsame, pathologische Instanzen in den Textdaten haben, wie ich es getan habe (einige davon, wie die Escape-Zeichen in einem Teil des Textes gelandet sind). Darüber hinaus möchten wir in listähnlichen Zeichenfolgen das Trennzeichen nur entfernen, wenn das Trennzeichen zwei Leerzeichen oder ein Nicht-Wort-Zeichen wie '-,' oder '-, ,,,' trennt.

NB: Ich spreche nicht über das Trennzeichen der CSV selbst. Nur von Instanzen innerhalb der CSV, in denen die Daten listenartig sind, dh eine cs-Zeichenfolge von Teilzeichenfolgen.

Vollständige Offenlegung: Ich habe nur etwa einen Monat lang Text manipuliert und erst in den letzten zwei Wochen einen regulären Ausdruck vorgenommen. Ich bin mir also sicher, dass mir einige Nuancen fehlen. Für kleinere Sammlungen von Zeichenfolgen (meine befinden sich in einem Datenrahmen von 12.000 Zeilen und 40 ungeraden Spalten) funktioniert dies als letzter Schritt nach einem Durchgang zum Entfernen von Fremdzeichen besonders gut, insbesondere wenn Sie an Ihrer Stelle zusätzliche Leerzeichen einfügen Sie möchten Text trennen, der durch ein Nicht-Wort-Zeichen verbunden ist, aber keine Leerzeichen hinzufügen, in denen zuvor keine vorhanden waren.

Ein Beispiel:

import re


text = "\"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, , , , \r, , \0, ff dd \n invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, \n i69rpofhfsp9t7c practice 20ignition - 20june \t\n .2134.pdf 2109                                                 \n\n\n\nklkjsdf\""

print(f"Here is the text as formatted:\n{text}\n")
print()
print("Trimming both the whitespaces and the non-word characters that follow them.")
print()
trim_ws_punctn = re.compile(r'[\s_]+?\W+')
clean_text = trim_ws_punctn.sub(' ', text)
print(clean_text)
print()
print("what about 'strip()'?")
print(f"Here is the text, formatted as is:\n{text}\n")
clean_text = text.strip(' \n\t\r')  # strip out whitespace?
print()
print(f"Here is the text, formatted as is:\n{clean_text}\n")

print()
print("Are 'text' and 'clean_text' unchanged?")
print(clean_text == text)

Dies gibt aus:

Here is the text as formatted:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf" 

using regex to trim both the whitespaces and the non-word characters that follow them.

"portfolio, derp, hello-world, hello-, world, founders, mentors, ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, ff, series a, exit, general mailing, fr, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk,  [email protected], dd invites,subscribed,, master, dd invites,subscribed, ff dd invites, subscribed, alumni spring 2012 deck: https: www.dropbox.com s, i69rpofhfsp9t7c practice 20ignition 20june 2134.pdf 2109 klkjsdf"

Very nice.
What about 'strip()'?

Here is the text, formatted as is:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"


Here is the text, after stipping with 'strip':


"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, [email protected], ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"
Are 'text' and 'clean_text' unchanged? 'True'

Der Streifen entfernt also jeweils ein Leerzeichen. Also im Fall der OP strip()ist das in Ordnung. Wenn die Dinge jedoch komplexer werden, können Regex und ein ähnliches Muster für allgemeinere Einstellungen von Wert sein.

sehen Sie es in Aktion

Joshua Fiddler
quelle
0

versuche zu übersetzen

>>> import string
>>> print '\t\r\n  hello \r\n world \t\r\n'

  hello 
 world  
>>> tr = string.maketrans(string.whitespace, ' '*len(string.whitespace))
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr)
'     hello    world    '
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr).replace(' ', '')
'helloworld'
海洋 顶端
quelle
0

Wenn Sie das Leerzeichen nur am Anfang und am Ende der Zeichenfolge abschneiden möchten, können Sie Folgendes tun:

some_string = "    Hello,    world!\n    "
new_string = some_string.strip()
# new_string is now "Hello,    world!"

Dies funktioniert ähnlich wie die QString :: trimmed () -Methode von Qt, da führende und nachfolgende Leerzeichen entfernt werden, während interne Leerzeichen in Ruhe gelassen werden.

Wenn Sie jedoch die QString :: simplified () -Methode von Qt möchten, mit der nicht nur führende und nachfolgende Leerzeichen entfernt, sondern auch alle aufeinanderfolgenden internen Leerzeichen in ein Leerzeichen "zerquetscht" werden, können Sie eine Kombination aus .split()und " ".joinwie folgt verwenden :

some_string = "\t    Hello,  \n\t  world!\n    "
new_string = " ".join(some_string.split())
# new_string is now "Hello, world!"

In diesem letzten Beispiel wurde jede Sequenz von internen Leerzeichen durch ein einzelnes Leerzeichen ersetzt, während das Leerzeichen weiterhin vom Anfang und Ende der Zeichenfolge abgeschnitten wurde.

J L
quelle
-1

Im Allgemeinen verwende ich die folgende Methode:

>>> myStr = "Hi\n Stack Over \r flow!"
>>> charList = [u"\u005Cn",u"\u005Cr",u"\u005Ct"]
>>> import re
>>> for i in charList:
        myStr = re.sub(i, r"", myStr)

>>> myStr
'Hi Stack Over  flow'

Hinweis: Dies dient nur zum Entfernen von "\ n", "\ r" und "\ t". Es werden keine zusätzlichen Leerzeichen entfernt.

Mayur Koshti
quelle
-2

zum Entfernen von Leerzeichen aus der Mitte der Zeichenfolge

$p = "ATGCGAC ACGATCGACC";
$p =~ s/\s//g;
print $p;

Ausgabe:

ATGCGACACGATCGACC
Meister Roshi
quelle
1
Diese Frage
bezieht sich auf
-17

Dadurch werden alle Leerzeichen und Zeilenumbrüche am Anfang und am Ende einer Zeichenfolge entfernt:

>>> s = "  \n\t  \n   some \n text \n     "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"
Rafe
quelle
8
Warum einen regulären Ausdruck verwenden, wenn s.strip()genau dies geschieht?
Ned Batchelder
1
s.strip()behandelt nur den anfänglichen Leerraum, nicht jedoch Leerzeichen, die nach dem Entfernen anderer unerwünschter Zeichen "entdeckt" wurden. Beachten Sie, dass dies sogar das Leerzeichen nach der endgültigen Führung entfernt\n
Rafe
Jemand hat diese Antwort abgelehnt, aber nicht erklärt, warum sie fehlerhaft ist. Schande über dich (@NedBatchelder, wenn die Abstimmung nicht war, bitte rückgängig machen, da ich deine Frage erklärt habe und du nichts erwähnt hast, was mit meiner Antwort tatsächlich gebrochen ist)
Rafe
10
Rafe, vielleicht möchten Sie es noch einmal überprüfen: s.strip()Erzeugt genau das gleiche Ergebnis wie Ihre Regex.
Ned Batchelder
3
@Safe, Sie verwechseln es mit Trimmen. Strip führt die erforderlichen Operationen aus.
iMitwe