从字符串中剥离标点符号的最佳方法

似乎应该有一个比这更简单的方法。

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中从字符串中剥离标点符号的注意事项。 详细说明请参考其他答案。

Python 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)

string.punctuation是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')

它还将剥离像~*+§$这样的字符,可能是或可能不是"标点符号&quot。 取决于一个人'的观点。

评论(2)

不一定更简单,但不同的方式,如果你对re家族更熟悉。

import re, string
s = "string. With. Punctuation?" # Sample string 
out = re.sub('[%s]' % re.escape(string.punctuation), '', s)
评论(3)

对于Python 3 str或Python 2 unicode值,str.translate()只接受一个字典。 编码点(整数)在该映射中被查找,任何映射到None的东西都会被删除。

如果要删除(一些?)标点符号,可以使用。

import string

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

dict.fromkeys()类方法使创建映射变得微不足道,根据键的序列将所有值设置为None

要删除*所有的标点符号,而不仅仅是ASCII标点符号,你的表需要更大一些。 参见J.F. Sebastian'的回答 (Python 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)

string.punctuation漏掉了现实世界中常用的大量标点符号。 那么有一个对非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中删除字符串中标点符号的最好方法,因为。

  • 它删除了所有Unicode标点
  • 它很容易修改,例如。 如果你想去掉标点符号,你可以去掉\{S},但保留$等符号。
  • 您可以对您要保留和删除的符号进行具体的规定,例如 /{Pd} 只删除破折号。
  • 这个regex还对空白进行了规范化处理。 它可以将制表符、回车符和其他奇怪的字符映射为漂亮的单空格。

这使用了Unicode字符属性,你可以在维基百科上阅读更多信息

1:

评论(0)

我还没有看到这个答案。 只需使用一个regex。 它删除了除了单词字符(\w)和数字字符(\d)以外的所有字符,后面还有一个空格字符(\s)。

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)

这是我写的一个函数。 它的效率不高,但很简单,你可以添加或删除任何你想要的标点符号。

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 中重写了 @Brian 的例子,并对其进行了修改,将 regex 编译步骤移到了函数内部。 我在这里的想法是把每一个步骤的时间都安排好,以使函数工作。 也许你使用的是分布式计算,不能在你的工作者之间共享regex对象,需要在每个工作者处有re.compile步骤。 另外,我很好奇的是,对Python 3的maketrans的两种不同实现进行时间上的调整。

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

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

另外,我还增加了另一个使用set的方法,我利用交集函数来减少迭代次数。

这是完整的代码。

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)

这里有一个不用regex的解决方案。

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)