从字符串中提取英语单词的Python方法
我有一个文档,每一行都是一个字符串。里面可能包含数字、非英语字母和单词,还有一些符号(比如 ! 和 *)。我想从每一行中提取出英语单词(英语单词之间用空格分开)。我的代码如下,这是我在进行映射-归约工作时的映射函数。不过,根据最终的结果,这个映射函数只计算了字母(比如 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 '%s\t%s' % (word, 1)
2 个回答
这里有两个问题:
line = re.sub("[^A-Za-z]", "", line.strip())
这行代码会把所有不是字母的东西都去掉,这样在后面分词的时候就会很困难。一个替代的解决办法是使用words = re.findall('[A-Za-z]', line)
这行代码。正如 @abarnert 提到的,现有的代码中
words
是一个字符串,使用for word in words
会逐个遍历每个字母。如果想把words
变成一个单词的列表,可以参考第一个解决办法。
其实你遇到了两个问题。
首先是这个:
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: