从字符串中提取英语单词的Python方法

4 投票
2 回答
13252 浏览
提问于 2025-04-20 08:51

我有一个文档,每一行都是一个字符串。里面可能包含数字、非英语字母和单词,还有一些符号(比如 ! 和 *)。我想从每一行中提取出英语单词(英语单词之间用空格分开)。我的代码如下,这是我在进行映射-归约工作时的映射函数。不过,根据最终的结果,这个映射函数只计算了字母(比如 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 个回答

0

这里有两个问题:

  1. line = re.sub("[^A-Za-z]", "", line.strip()) 这行代码会把所有不是字母的东西都去掉,这样在后面分词的时候就会很困难。一个替代的解决办法是使用 words = re.findall('[A-Za-z]', line) 这行代码。

  2. 正如 @abarnert 提到的,现有的代码中 words 是一个字符串,使用 for word in words 会逐个遍历每个字母。如果想把 words 变成一个单词的列表,可以参考第一个解决办法。

7

其实你遇到了两个问题。

首先是这个:

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:

撰写回答