Як видалити розділові знаки з рядка в Python 3.x за допомогою .translate ()?


77

Я хочу видалити всі розділові знаки з текстового файлу методом .translate (). Здається, це добре працює під Python 2.x, але під Python 3.4, здається, нічого не робить.

Мій код такий, а вихідний результат такий самий, як вхідний текст.

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

Відповіді:


173

Вам потрібно створити таблицю перекладів, використовуючи maketransте, що ви переходите до str.translateметоду.

У Python 3.1 та новіших версіях maketransтепер є статичним методом для strтипу , тому ви можете використовувати його для створення перекладу кожної пунктуації, яку ви хочете 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))

Це повинно вивести:

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

5
Це добре зроблено. Прикро, що найкращі результати Google для цієї теми застаріли, повільніші чи складніші.
розрив

1
Здається, string.punctuationце не включає цитати. Як би ми налаштували цей код для обрізки за допомогою клавіш string.punctuation, а також символів, заданих користувачем? А чи заява?
Араш Говайда

1
@ArashHowaida string.punctuationвключає лапки (як подвійні, так і одинарні) - навіть у моєму прикладі він видаляє подвійні лапки. Якщо ви хочете , щоб налаштувати то , що отримує роздягли в доповненні до str.punctuation, просто зчепити string.punctuationз рядком символів , які ви також хочете видалити, як translator = str.maketrans({key: None for key in string.punctuation + 'abc'})якщо ви хочете , щоб видалити знаки пунктуації та входження символів a, b, або c.
wkl

Мої котирування повинні мати деякі проблеми з кодуванням, про що варто знати. Дякую!
Араш Говайда

1
str.maketrans('', '', string.punctuation)також спрацює. Немає потреби в циклі, в будь-якому випадку, навіть тут str.maketrans(dict.fromkeys(string.punctuation))було б краще.
Мартін Пітерс

25

Підпис виклику str.translate змінився, і, очевидно, параметр deletechars був видалений. Ви могли б використовувати

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

замість цього, або створіть таблицю, як показано в іншій відповіді.


1
(@Birryree приклад ( stackoverflow.com/a/34294398/1656850 ) благає не погодитися з вашим старіння едикту на string.translate ;-)
boardrider

Ти правий. Я неправильно зрозумів документацію з цього приводу. Змінився лише підпис виклику: str.translate бере як параметр лише таблицю, а більше не видаляє символи (як видно з відповіді birryree). Я відредагую свою відповідь відповідно.
elzell,

Це єдине рішення, яке мені вдалося знайти, сумісне з Python 2.7 / 3.6. Я не міг знайти жодного рішення для використання translate (), яке б працювало як для Python 2.7, так і для 3.6.
близьке

23

У python3.x це можна зробити за допомогою:

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

3

Я щойно порівняв три методи за швидкістю. translateповільніше, ніж re.sub(з попереднім складанням) приблизно в 10 разів. І str.replaceце швидше, ніж re.subприблизно в 3 рази. До str.replaceЯ маю в виду:

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

2
Я думаю , що ви робите це неправильно тести бігають (прийняті в перекладі тестової частини для Python3) з stackoverflow.com/a/266162/4249707 на Python 3.6.0b4 і як багато років тому замінити відстій. Мої результати - набори: 2,7033574236556888 регулярний вираз: 0,9831533581018448 перекласти: 1,837449918501079 замінити: 5,498765277676284
Ель Русо

0

Пізня відповідь, але щоб видалити всі розділові знаки на python> = 3.6, ви також можете використовувати:

import re, string

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

Демо

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.