2015-12-15 21 views
29

Chcę usunąć wszystkie znaki interpunkcyjne z pliku tekstowego za pomocą metody .translate(). Wydaje się, że działa dobrze w Pythonie 2.x, ale w Pythonie 3.4 nic nie robi.Jak usunąć znaki interpunkcyjne z łańcucha znaków w Pythonie 3.x za pomocą .translate()?

Mój kod jest następujący, a wynik jest taki sam jak tekst wejściowy.

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

Odpowiedz

8

Sygnatura wywołania str.translate uległa zmianie i najwyraźniej usunięto parametr deletechars. Zamiast tego można zamiast tego użyć tabeli lub utworzyć tabelę zgodnie z drugą odpowiedzią.

+0

idealny, działa rewelacyjnie! – cybujan

+0

(przykład @birryree (http://stackoverflow.com/a/34294398/1656850) prosi, aby nie zgadzać się z edycją deprecation na string.translate ;-) – boardrider

+0

Masz rację. Źle zrozumiałem dokumentację na ten temat. Zmienił się tylko podpis wywołania: str.translate przyjmuje tylko tabelę jako parametr i nie usuwa już deletechar (jak widać w odpowiedzi birryree). Odpowiednio edytuję swoją odpowiedź. – elzell

84

Musisz utworzyć tabelę translacji za pomocą maketrans, którą przekazujesz do metody str.translate.

W języku Python 3.1 i nowszym maketrans jest teraz static-method on the str type, więc można go użyć do utworzenia tłumaczenia każdej interpunkcji, która ma być 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)) 

Powinno to wyjście:

string with punctuation inside of it Does this work I hope so 
+1

To ładnie zrobione. To niefortunne, że najlepsze wyniki Google dla tego tematu są przestarzałe, wolniejsze lub trudniejsze do naśladowania. – rurp

+1

Wygląda na to, że 'string.punctuation' nie zawiera cudzysłowów. W jaki sposób ulepszylibyśmy ten kod do przycinania za pomocą klawiszy w 'string.punctuation', jak również znaków podanych przez użytkownika? An lub oświadczenie? –

+1

@ArashHowaida 'string.punctuation' zawiera cudzysłowy (zarówno podwójne, jak i pojedyncze) - nawet w moim przykładzie usuwa podwójne cudzysłowy. Jeśli chcesz dostosować to, co zostanie usunięte poza 'str.punctuation', po prostu połącz' string.punctuation' z łańcuchem znaków, który również chcesz usunąć, np. 'Translator = str.maketrans ({key: None dla klucza w łańcuchu znaków .punctuation + 'abc'})), jeśli chcesz usunąć interpunkcję i wszelkie wystąpienia znaków 'a',' b' lub 'c'. – birryree

0

Właśnie porównano trzy metody, których autorem jest szybkość. translate jest wolniejszy niż re.sub (z prekomknięciem) w około 10 razy. I str.replace jest szybsze niż re.sub około 3 razy. Przez str.replace To znaczy:

for ch in string.punctuation:                          
    s = s.replace(ch, "'") 
+1

Myślę, że robisz to źle Uruchomiłem testy (przyjęte w tłumaczeniu części testowej dla python3) z http://stackoverflow.com/a/266162/4249707 na Pythonie 3.6.0b4 i jak wiele lat temu zastąpić ssie. Moje wyniki - zestawy: 2.7033574236556888 regex: 0,9831533581018448 tłumaczyć: 1,837449918501079 wymienić: 5,498765277676284 –

4

W python3.x, można to zrobić za pomocą:

import string 
#make translator object 
translator=str.maketrans('','',string.punctuation) 
string_name=string_name.translate(translator) 
Powiązane problemy