Wie entferne ich Satzzeichen aus einer Zeichenfolge in Python 3.x mit .translate ()?

75

Ich möchte alle Satzzeichen mit der Methode .translate () aus einer Textdatei entfernen. Es scheint unter Python 2.x gut zu funktionieren, aber unter Python 3.4 scheint es nichts zu tun.

Mein Code lautet wie folgt und die Ausgabe entspricht der Eingabe von Text.

import string
fhand = open("Hemingway.txt")
for fline in fhand:
    fline = fline.rstrip()
    print(fline.translate(string.punctuation))
Cybujan
quelle

Antworten:

171

Sie müssen eine Übersetzungstabelle erstellen maketrans, die Sie an die str.translateMethode übergeben.

In Python 3.1 und höher maketransist jetzt eine statische Methode für den strTyp , sodass Sie damit eine Übersetzung jeder gewünschten Interpunktion erstellen können None.

import string

# Thanks to Martijn Pieters for this improved version

# This uses the 3-argument version of str.maketrans
# with arguments (x, y, z) where 'x' and 'y'
# must be equal-length strings and characters in 'x'
# are replaced by characters in 'y'. 'z'
# is a string (string.punctuation here)
# where each character in the string is mapped
# to None
translator = str.maketrans('', '', string.punctuation)

# This is an alternative that creates a dictionary mapping
# of every character from string.punctuation to None (this will
# also work)
#translator = str.maketrans(dict.fromkeys(string.punctuation))

s = 'string with "punctuation" inside of it! Does this work? I hope so.'

# pass the translator to the string's translate method.
print(s.translate(translator))

Dies sollte Folgendes ausgeben:

string with punctuation inside of it Does this work I hope so
wkl
quelle
5
Das ist gut gemacht. Es ist bedauerlich, dass die besten Google-Ergebnisse für dieses Thema veraltet, langsamer oder schwieriger zu verfolgen sind.
rurp
1
Es scheint, dass string.punctuationdies keine Anführungszeichen enthält. Wie würden wir diesen Code optimieren, um die Tasten string.punctuationsowie die benutzerdefinierten Zeichen zu kürzen? Eine oder Aussage?
Arash Howaida
1
@ArashHowaida string.punctuationenthält Anführungszeichen (sowohl doppelte als auch einfache) - selbst in meinem Beispiel werden die doppelten Anführungszeichen entfernt. Wenn Sie anpassen möchten , was zusätzlich zu gestrippt wird str.punctuation, nur verketten string.punctuationmit einer Reihe von Zeichen , die Sie auch entfernt werden sollen, wie translator = str.maketrans({key: None for key in string.punctuation + 'abc'})wenn Sie Interpunktion und alle Vorkommen der Zeichen entfernen wollte a, boder c.
wkl
Meine Zitate müssen einige Codierungsprobleme aufweisen, gut zu wissen. Vielen Dank!
Arash Howaida
1
str.maketrans('', '', string.punctuation)würde auch funktionieren. Es besteht keine Notwendigkeit, eine Schleife zu str.maketrans(dict.fromkeys(string.punctuation))erstellen , jedenfalls wäre dies hier sogar besser.
Martijn Pieters
25

Die Aufrufsignatur von str.translate hat sich geändert und anscheinend wurde der Parameter deletechars entfernt. Du könntest benutzen

import re
fline = re.sub('['+string.punctuation+']', '', fline)

oder erstellen Sie stattdessen eine Tabelle wie in der anderen Antwort gezeigt.

elzell
quelle
1
(@birryree Beispiel ( stackoverflow.com/a/34294398/1656850 ) bittet, mit Ihrem Verfallsedikt auf string.translate nicht einverstanden zu sein ;-)
Boardrider
Du hast recht. Ich habe die Dokumentation zu diesem Punkt falsch verstanden. Nur die Anrufsignatur hat sich geändert: str.translate verwendet nur eine Tabelle als Parameter und löscht keine Zeichen mehr (wie in der Antwort von birryree zu sehen). Ich werde meine Antwort entsprechend bearbeiten.
Elzell
Dies ist die einzige Lösung, die Python 2.7 / 3.6-kompatibel ist. Ich konnte keine Lösung für translate () finden, die sowohl für Python 2.7 als auch für Python 3.6 funktioniert.
nahe
23

In python3.x kann dies folgendermaßen erfolgen:

import string
#make translator object
translator=str.maketrans('','',string.punctuation)
string_name=string_name.translate(translator)
Mayank Kumar
quelle
3

Ich habe gerade die drei Methoden nach Geschwindigkeit verglichen. translateist langsamer als re.sub(mit Vorkomilation) in etwa 10 mal. Und str.replaceist schneller als re.subin etwa 3 mal. Mit str.replacemeine ich:

for ch in string.punctuation:                                                                                                     
    s = s.replace(ch, "'") 
imbolc
quelle
2
Ich denke, Sie machen es falsch. Ich führe Tests (übernommen im Übersetzungstestteil für Python3) von stackoverflow.com/a/266162/4249707 auf Python 3.6.0b4 aus und ersetze wie vor vielen Jahren Sucks. Meine Ergebnisse - Sätze: 2.7033574236556888 Regex: 0.9831533581018448 übersetzen: 1.837449918501079 ersetzen: 5.498765277676284
El Ruso
0

Späte Antwort, aber um alle Interpunktion auf Python> = 3.6 zu entfernen, können Sie auch Folgendes verwenden:

import re, string

clean_string = re.sub(rf"[{string.punctuation}]", "", dirty_string)

Demo

Pedro Lobito
quelle