我想我想做的是一项相当常见的任务,但我在网上找不到任何参考资料。我有带标点符号的文本,我想要一个单词列表。
"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()只对一个参数有效,所以在用空格拆分后,所有单词都带有标点符号。有什么想法吗?
当前回答
另一种方式,不使用正则表达式
import string
punc = string.punctuation
thestring = "Hey, you - what are you doing here!?"
s = list(thestring)
''.join([o for o in s if not o in punc]).split()
其他回答
这是我的看法。。。。
def split_string(source,splitlist):
splits = frozenset(splitlist)
l = []
s1 = ""
for c in source:
if c in splits:
if s1:
l.append(s1)
s1 = ""
else:
print s1
s1 = s1 + c
if s1:
l.append(s1)
return l
>>>out = split_string("First Name,Last Name,Street Address,City,State,Zip Code",",")
>>>print out
>>>['First Name', 'Last Name', 'Street Address', 'City', 'State', 'Zip Code']
join = lambda x: sum(x,[]) # a.k.a. flatten1([[1],[2,3],[4]]) -> [1,2,3,4]
# ...alternatively...
join = lambda lists: [x for l in lists for x in l]
然后变成三行:
fragments = [text]
for token in tokens:
fragments = join(f.split(token) for f in fragments)
解释
这就是Haskell中所谓的列表monad。monad背后的想法是,一旦“进入monad”,你就“留在monad”直到有什么东西把你带走。例如,在Haskell中,假设您将python range(n)->[1,2,…,n]函数映射到List上。如果结果是一个List,它将被附加到List中,所以你会得到类似map(range,[3,4,1])->[0,1,2,0,1,2,3,0]的结果。这被称为map append(或mappend,或类似的东西)。这里的想法是,你已经得到了你正在应用的这个操作(对一个令牌进行拆分),每当你这样做时,你都会将结果加入到列表中。
您可以将其抽象为一个函数,并在默认情况下使用token=string.p标点符号。
这种方法的优点:
这种方法(与基于正则表达式的简单方法不同)可以使用任意长度的令牌(正则表达式也可以使用更高级的语法)。你不仅仅局限于象征;您可以使用任意逻辑来代替每个标记,例如,其中一个“标记”可以是一个函数,该函数根据括号的嵌套程度进行拆分。
我遇到了类似的困境,不想使用“re”模块。
def my_split(s, seps):
res = [s]
for sep in seps:
s, res = res, []
for seq in s:
res += seq.split(sep)
return res
print my_split('1111 2222 3333;4444,5555;6666', [' ', ';', ','])
['1111', '', '2222', '3333', '4444', '5555', '6666']
首先,在循环中执行任何RegEx操作之前,请始终使用re.compile(),因为它的工作速度比正常操作快。
因此,对于您的问题,首先编译模式,然后对其执行操作。
import re
DATA = "Hey, you - what are you doing here!?"
reg_tok = re.compile("[\w']+")
print reg_tok.findall(DATA)
我喜欢pprzemek的解决方案,因为它不假设分隔符是单个字符,也不试图利用正则表达式(如果分隔符的数量太长,这将不会很好地工作)。
为清晰起见,以下是上述解决方案的更可读版本:
def split_string_on_multiple_separators(input_string, separators):
buffer = [input_string]
for sep in separators:
strings = buffer
buffer = [] # reset the buffer
for s in strings:
buffer = buffer + s.split(sep)
return buffer