我有一个文件,每行都是一个字符串。它可能包含数字,非英文字母和单词,符号(例如!和*)。我想从每一行中提取英语单词(英语单词用空格分隔)。 我的代码如下,这是map-reduce作业的map函数。但是,根据最终结果,此映射器函数仅生成字母(例如a,b,c)频率计数。任何人都可以帮我找到这个bug吗?谢谢
import sys
import re
for line in sys.stdin:
line = re.sub("[^A-Za-z]", "", line.strip())
line = line.lower()
words = ' '.join(line.split())
for word in words:
print '%s\t%s' % (word, 1)
答案 0 :(得分:3)
你实际上有两个问题。
首先,这个:
line = re.sub("[^A-Za-z]", "", line.strip())
这将删除该行中的所有非字母。这意味着你不再有任何空格可以拆分,因此无法将其分成单词。
接下来,即使您没有这样做,也可以这样做:
words = ' '.join(line.split())
这不会给你一个单词列表,这会给你一个字符串,所有这些单词连接在一起。 (基本上,原始行将所有空格转换为单个空格。)
所以,在下一行中,当你这样做时:
for word in words:
您正在迭代一个字符串,这意味着每个word
都是一个字符。因为这就是字符串:字符的可迭代。
如果你想要每个单词(正如你的变量名所暗示的那样),你已经拥有了这些单词,问题是你将它们加入了一个字符串。只是不要这样做:
words = line.split()
for word in words:
或者,如果你想删除除字母和空格之外的东西,可以使用一个正则表达式去除除字母和空格之外的所有内容,而不是删除字母以外的所有内容,包括空格:
line = re.sub(r"[^A-Za-z\s]", "", line.strip())
words = line.split()
for word in words:
然而,这种模式可能仍然不是你想要的。您真的想将'abc1def'
转换为单个字符串'abcdef'
,还是转换为两个字符串'abc'
和'def'
?你可能想要这个:
line = re.sub(r"[^A-Za-z]", " ", line.strip())
words = line.split()
for word in words:
......或只是:
words = re.split(r"[^A-Za-z]", line.strip())
for word in words:
答案 1 :(得分:0)
这里有两个问题:
line = re.sub("[^A-Za-z]", "", line.strip())
会删除所有非字符,因此很难在后续阶段拆分字词。另一种解决方案就是这样words = re.findall('[A-Za-z]', line)
正如@abarnert所提到的,在现有代码words
中是一个字符串,for word in words
将迭代每个字母。要将words
作为单词列表,您可以按照1。