我有一个文档,每一行都是一个字符串。它可能包含数字、非英文字母和单词、符号(如!和*)。我想从每一行中提取英语单词(英语单词用空格隔开)。我的代码如下,这是我的map reduce作业的map函数。但是,根据最终结果,此映射器函数只生成字母(如a、b、c)频率计数。有人能帮我找到虫子吗?感谢
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 '%st%s' % (word, 1)
您实际上有两个问题。
首先,这个:
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-zs]", "", 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:
这里有两个问题:
-
line = re.sub("[^A-Za-z]", "", line.strip())
将删除所有非字符,使得在后续阶段很难拆分单词。另一种解决方案类似于words = re.findall('[A-Za-z]', line)
-
正如@abarnert所提到的,在现有代码中,
words
是一个字符串,for word in words
将迭代每个字母。要获得words
作为单词列表,可以按照1。