我想我想做的是一项相当常见的任务,但我在网上找不到任何参考资料。我有带标点符号的文本,我想要一个单词列表。
"Hey, you - what are you doing here!?"
应该是
['hey', 'you', 'what', 'are', 'you', 'doing', 'here']
但Python的str.split()只对一个参数有效,所以在用空格拆分后,所有单词都带有标点符号。有什么想法吗?
我想我想做的是一项相当常见的任务,但我在网上找不到任何参考资料。我有带标点符号的文本,我想要一个单词列表。
"Hey, you - what are you doing here!?"
应该是
['hey', 'you', 'what', 'are', 'you', 'doing', 'here']
但Python的str.split()只对一个参数有效,所以在用空格拆分后,所有单词都带有标点符号。有什么想法吗?
当前回答
专业提示:使用string.translate进行Python最快的字符串操作。
一些证据。。。
首先,缓慢的方式(抱歉pprzemek):
>>> import timeit
>>> S = 'Hey, you - what are you doing here!?'
>>> def my_split(s, seps):
... res = [s]
... for sep in seps:
... s, res = res, []
... for seq in s:
... res += seq.split(sep)
... return res
...
>>> timeit.Timer('my_split(S, punctuation)', 'from __main__ import S,my_split; from string import punctuation').timeit()
54.65477919578552
接下来,我们使用re.findall()(如建议的答案所示)。更快:
>>> timeit.Timer('findall(r"\w+", S)', 'from __main__ import S; from re import findall').timeit()
4.194725036621094
最后,我们使用translate:
>>> from string import translate,maketrans,punctuation
>>> T = maketrans(punctuation, ' '*len(punctuation))
>>> timeit.Timer('translate(S, T).split()', 'from __main__ import S,T,translate').timeit()
1.2835021018981934
说明:
string.translate是用C实现的,与Python中的许多字符串操作函数不同,string.ttranslate不会生成新字符串。所以它的速度和字符串替换一样快。
不过,这有点尴尬,因为它需要一个翻译表来实现这一魔术。您可以使用maketrans()方便函数创建转换表。这里的目标是将所有不需要的字符转换为空格。一换一的替代品。同样,不会产生新数据。所以这很快!
接下来,我们使用旧的split()。默认情况下,split()将对所有空白字符进行操作,将它们分组以进行拆分。结果将是您想要的单词列表。而且这种方法几乎比re.findall()快4倍!
其他回答
试试看:
import re
phrase = "Hey, you - what are you doing here!?"
matches = re.findall('\w+', phrase)
print matches
这将打印['Hey','you','what','are','you','doing','here']
我认为以下是满足您需求的最佳答案:
\W+可能适合这种情况,但可能不适合其他情况。
filter(None, re.compile('[ |,|\-|!|?]').split( "Hey, you - what are you doing here!?")
在Python3中,您可以使用PY4E-PythonforEveryone中的方法。
我们可以通过使用字符串方法lower、标点符号和translate来解决这两个问题。翻译是最微妙的方法。以下是翻译文档:
your_string.translate(your_string.maketrans(fromstr,tostr,deletestr))
将fromstr中的字符替换为tostr中相同位置的字符,并删除deletestr中的所有字符。fromstr和tostr可以是空字符串,并且可以省略deletestr参数。
您可以看到“标点符号”:
In [10]: import string
In [11]: string.punctuation
Out[11]: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
例如:
In [12]: your_str = "Hey, you - what are you doing here!?"
In [13]: line = your_str.translate(your_str.maketrans('', '', string.punctuation))
In [14]: line = line.lower()
In [15]: words = line.split()
In [16]: print(words)
['hey', 'you', 'what', 'are', 'you', 'doing', 'here']
有关详细信息,请参阅:
PY4E-面向每个人的Python字符串转换str.maketransPython字符串maketrans()方法
创建一个函数,将两个字符串(要拆分的源字符串和分隔符的拆分列表字符串)作为输入,并输出拆分单词列表:
def split_string(source, splitlist):
output = [] # output list of cleaned words
atsplit = True
for char in source:
if char in splitlist:
atsplit = True
else:
if atsplit:
output.append(char) # append new word after split
atsplit = False
else:
output[-1] = output[-1] + char # continue copying characters until next split
return output
这是一个有一些解释的答案。
st = "Hey, you - what are you doing here!?"
# replace all the non alpha-numeric with space and then join.
new_string = ''.join([x.replace(x, ' ') if not x.isalnum() else x for x in st])
# output of new_string
'Hey you what are you doing here '
# str.split() will remove all the empty string if separator is not provided
new_list = new_string.split()
# output of new_list
['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']
# we can join it to get a complete string without any non alpha-numeric character
' '.join(new_list)
# output
'Hey you what are you doing'
或者在一行中,我们可以这样做:
(''.join([x.replace(x, ' ') if not x.isalnum() else x for x in st])).split()
# output
['Hey', 'you', 'what', 'are', 'you', 'doing', 'here']
更新的答案