Лучший способ удаления знаков препинания из строки

Кажется, что должен быть более простой способ, чем:

import string
s = "string. With. Punctuation?" # Sample string 
out = s.translate(string.maketrans("",""), string.punctuation)

Так ли это?

Комментарии к вопросу (7)
Решение

С точки зрения эффективности, вы не сможете победить

s.translate(None, string.punctuation)

Для более высоких версий Python используйте следующий код:

s.translate(str.maketrans('', '', string.punctuation))

Он выполняет необработанные строковые операции на C с помощью таблицы поиска - мало что может превзойти это, кроме написания собственного кода на C.

Если скорость не волнует, можно воспользоваться другим вариантом:

exclude = set(string.punctuation)
s = ''.join(ch for ch in s if ch not in exclude)

Это быстрее, чем s.replace для каждого символа, но не будет работать так же хорошо, как подходы не на чистом python, такие как regexes или string.translate, как видно из приведенных ниже таймингов. Для такого типа задач выгодно решать их на как можно более низком уровне.

Временной код:

import re, string, timeit

s = "string. With. Punctuation"
exclude = set(string.punctuation)
table = string.maketrans("","")
regex = re.compile('[%s]' % re.escape(string.punctuation))

def test_set(s):
    return ''.join(ch for ch in s if ch not in exclude)

def test_re(s):  # From Vinko's solution, with fix.
    return regex.sub('', s)

def test_trans(s):
    return s.translate(table, string.punctuation)

def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s

print "sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000)
print "regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000)
print "translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000)
print "replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000)

Это дает следующие результаты:

sets      : 19.8566138744
regex     : 6.86155414581
translate : 2.12455511093
replace   : 28.4436721802
Комментарии (11)

Регулярные выражения достаточно просты, если вы их знаете.

import re
s = "string. With. Punctuation?"
s = re.sub(r'[^\w\s]','',s)
Комментарии (4)

Для удобства использования, я подводить к сведению чередование препинания из строки в Python 2 и Python 3. Пожалуйста, обратитесь к другим ответы за подробное описание.


Питон 2

import string

s = "string. With. Punctuation?"
table = string.maketrans("","")
new_s = s.translate(table, string.punctuation)      # Output: string without punctuation

В Python 3

import string

s = "string. With. Punctuation?"
table = str.maketrans(dict.fromkeys(string.punctuation))  # OR {key: None for key in string.punctuation}
new_s = s.translate(table)                          # Output: string without punctuation
Комментарии (0)
myString.translate(None, string.punctuation)
Комментарии (7)

Обычно я использую что-то вроде этого:

>>> s = "string. With. Punctuation?" # Sample string
>>> import string
>>> for c in string.punctuation:
...     s= s.replace(c,"")
...
>>> s
'string With Punctuation'
Комментарии (2)

строку.пунктуация` является ASCII только! Более правильно (но гораздо медленнее) способ заключается в использовании модуль unicodedata:

# -*- coding: utf-8 -*-
from unicodedata import category
s = u'String — with -  «punctation »...'
s = ''.join(ch for ch in s if category(ch)[0] != 'P')
print 'stripped', s

Можно обобщить и прокладки других типов персонажей, а также:

''.join(ch for ch in s if category(ch)[0] != 'SP')

Он также удалит символы, такие как~*+§$ которые могут или не могут быть "пунктуация" и в зависимости от'с точки зрения.

Комментарии (2)

Не обязательно более простой, но другой способ, если вы лучше знакомы с семейством re.

import re, string
s = "string. With. Punctuation?" # Sample string 
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)
Комментарии (3)

Для Python 3 Ул или Python 2 Юникод значения, ул. перевести() принимает только словарем; коды (чисел) ищутся в том, что сопоставление и ничего отображенный на None удалена.

Снять (какой?) пунктуация затем использовать:

import string

remove_punct_map = dict.fromkeys(map(ord, string.punctuation))
s.translate(remove_punct_map)

В дикт.fromkeys() метод класса делает его тривиальным, чтобы создать сопоставление, установка всех значений в none на основе последовательности клавиш.

Чтобы удалить все знаки препинания, а не только ASCII символы пунктуации, ваш стол должен быть немного больше; см. Джей Ф. Себастьян'ы answer (питон 3 версии):

import unicodedata
import sys

remove_punct_map = dict.fromkeys(i for i in range(sys.maxunicode)
                                 if unicodedata.category(chr(i)).startswith('P'))
Комментарии (4)

строку.пунктуация` не пропускает грузы из знаков препинания, которые обычно используются в реальном мире. Как насчет решения, которое работает для не-ASCII знаков препинания?

import regex
s = u"string. With. Some・Really Weird、Non?ASCII。 「(Punctuation)」?"
remove = regex.compile(ur'[\p{C}|\p{M}|\p{P}|\p{S}|\p{Z}]+', regex.UNICODE)
remove.sub(u" ", s).strip()

Лично я считаю, что это лучший способ, чтобы удалить знаки препинания из строки в Python, потому что:

  • Он удаляет все знаки препинания Юникод
  • Она'ы легко изменяемым, например, вы можете удалить \{ы} если вы хотите, чтобы удалить знаки препинания, но держать такие символы, как $.
  • Вы можете получить очень конкретную информацию о то, что вы хотите сохранить, и то, что вы хотите удалить, например \{др} только убрать дефисы.
  • Это регулярное выражение также нормализует пробел. Он отображает символы табуляции, символы возврата каретки, и другие странности в Ниццу, одиночными пробелами.

При этом используются свойства символов Юникода, который вы можете узнать больше о Википедии.

Комментарии (0)

Я не'т видел этот ответ. Просто использовать регулярное выражение; она удаляет все символы кроме буквенных символов () и число символов (), сопровождаемый пробельный символ ():

import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(ur'[^\w\d\s]+', '', s)
Комментарии (3)

Здесь'ы легко для Python 3.5:

import string
"l*ots! o(f. p@u)n[c}t]u[a'ti\"on#$^?/".translate(str.maketrans({a:None for a in string.punctuation}))
Комментарии (0)

Вот функцию я написал. Это's не очень эффективно, но просто и вы можете добавлять или удалять любые знаки препинания, что вы хотите:

def stripPunc(wordList):
    """Strips punctuation from list of words"""
    puncList = [".",";",":","!","?","/","\\",",","#","@","$","&",")","(","\""]
    for punc in puncList:
        for word in wordList:
            wordList=[word.replace(punc,'') for word in wordList]
    return wordList
Комментарии (0)

Это может не быть лучшим решением, но это, как я это сделал.

import string
f = lambda x: ''.join([i for i in x if i not in string.punctuation])
Комментарии (0)

Просто как обновление, я переписал @Брайан примеру в Python 3 и внесенные в нее изменения, чтобы двигаться регулярное выражение компилируется в функцию. Моя мысль заключалась в том, чтобы каждый шаг, необходимый для того чтобы сделать функцию работы. Возможно, вы используете распределенных вычислений и может'Т есть выражение общих объектов между рабочими и должны быть повторно.шаг компиляции на каждого работника. Кроме того, мне было любопытно время двух разных реализаций maketrans для Python 3

table = str.maketrans({key: None for key in string.punctuation})

против

table = str.maketrans('', '', string.punctuation)

Плюс я добавил еще один метод использования набора, где я использую функцию пересечение, чтобы уменьшить количество итераций.

Это полный код:

import re, string, timeit

s = "string. With. Punctuation"

def test_set(s):
    exclude = set(string.punctuation)
    return ''.join(ch for ch in s if ch not in exclude)

def test_set2(s):
    _punctuation = set(string.punctuation)
    for punct in set(s).intersection(_punctuation):
        s = s.replace(punct, ' ')
    return ' '.join(s.split())

def test_re(s):  # From Vinko's solution, with fix.
    regex = re.compile('[%s]' % re.escape(string.punctuation))
    return regex.sub('', s)

def test_trans(s):
    table = str.maketrans({key: None for key in string.punctuation})
    return s.translate(table)

def test_trans2(s):
    table = str.maketrans('', '', string.punctuation)
    return(s.translate(table))

def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s

print("sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000))
print("sets2      :",timeit.Timer('f(s)', 'from __main__ import s,test_set2 as f').timeit(1000000))
print("regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000))
print("translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000))
print("translate2 :",timeit.Timer('f(s)', 'from __main__ import s,test_trans2 as f').timeit(1000000))
print("replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000))

Это мои результаты:

sets      : 3.1830138750374317
sets2      : 2.189873124472797
regex     : 7.142953420989215
translate : 4.243278483860195
translate2 : 2.427158243022859
replace   : 4.579746678471565
Комментарии (0)
>>> s = "string. With. Punctuation?"
>>> s = re.sub(r'[^\w\s]','',s)
>>> re.split(r'\s*', s)

['string', 'With', 'Punctuation']
Комментарии (1)

Здесь'ы решение без регулярных выражений.

import string

input_text = "!where??and!!or$$then:)"
punctuation_replacer = string.maketrans(string.punctuation, ' '*len(string.punctuation))    
print ' '.join(input_text.translate(punctuation_replacer).split()).strip()

output>> where and or then
  • Заменяет знаки препинания с пробелами
  • Замены нескольких пробелов между словами один пробел
  • Уберите пробелы, если таковые имеются полосы()
Комментарии (0)
import re
s = "string. With. Punctuation?" # Sample string 
out = re.sub(r'[^a-zA-Z0-9\s]', '', s)
Комментарии (1)

Один вкладыш может быть полезным в не очень строгих случаях:

''.join([c for c in s if c.isalnum() or c.isspace()])
Комментарии (0)
#FIRST METHOD
#Storing all punctuations in a variable    
punctuation='!?,.:;"\')(_-'
newstring='' #Creating empty string
word=raw_input("Enter string: ")
for i in word:
     if(i not in punctuation):
                  newstring+=i
print "The string without punctuation is",newstring

#SECOND METHOD
word=raw_input("Enter string: ")
punctuation='!?,.:;"\')(_-'
newstring=word.translate(None,punctuation)
print "The string without punctuation is",newstring

#Output for both methods
Enter string: hello! welcome -to_python(programming.language)??,
The string without punctuation is: hello welcome topythonprogramminglanguage
Комментарии (0)
with open('one.txt','r')as myFile:

    str1=myFile.read()

    print(str1)

    punctuation = ['(', ')', '?', ':', ';', ',', '.', '!', '/', '"', "'"] 

for i in punctuation:

        str1 = str1.replace(i," ") 
        myList=[]
        myList.extend(str1.split(" "))
print (str1) 
for i in myList:

    print(i,end='\n')
    print ("____________")
Комментарии (0)