有没有库可以将句子拆分成单词列表?

4 投票
5 回答
4084 浏览
提问于 2025-04-16 23:23

我在看Python的nltk库,但它把won't分成了['wo', "n't"]。有没有更好用的库可以处理这个问题?

我知道我可以用某种正则表达式来解决这个问题,但我想找一个库或工具,因为这样会更直接。例如,在用基本的正则表达式处理句号和逗号后,我发现像'Mr. '这样的词会让系统出错。

(@artsiom)

如果句子是"you won't?",用split()会得到["you", "won't?"]。这样就多了一个'?',我还得处理这个问题。我希望能找到一种经过验证的方法,能解决像上面提到的那些小问题,还有很多我肯定会遇到的例外情况。当然,如果找不到合适的,我还是会用split(regex)来处理。

5 个回答

3

@Karthick,这里有一个我很久以前用来把文本分割成单词列表的简单算法:

  1. 输入文本
  2. 逐个字符地遍历文本。
  3. 如果当前字符是字母,就把它加到一个单词里。如果不是字母,就把之前创建的单词放到一个列表里,然后开始一个新单词。

alphabet = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
text = "I won't answer this question!"

word = ''
wordlist = []

for c in text:
    if c in alphabet:
        word += c
    else:
        if len(word) > 0:
            wordlist.append(word)
        word = ''

print wordlist
['I', "won't", 'answer', 'this', 'question']

这只是一个起点,你完全可以修改这个算法,让它更聪明一些 :)

5

尽管你可能有不同的看法,但NLTK绝对是你最好的选择。你不会找到比里面的分词器更“经过验证”的方法了(因为其中一些是基于专门训练的分类器)。你只需要选择适合你需求的分词器。我们来看下面这句话:

I am a happy teapot that won't do stuff?

接下来是NLTK中各种分词器如何处理这句话的。

TreebankWordTokenizer

I am a happy teapot that wo n't do stuff ?

WordPunctTokenizer

I am a happy teapot that won ' t do stuff ?

PunktWordTokenizer

I am a happy teapot that won 't do stuff ?

WhitespaceTokenizer

I am a happy teapot that won't do stuff?

你最好的选择可能是结合几种方法。例如,你可以先用PunktSentenceTokenizer来分割句子,这通常非常准确。然后,对于每个句子,如果有的话,去掉结尾的标点符号。接着使用WhitespaceTokenizer,这样你就能避免最后的标点和单词合并,比如stuff?,因为你已经从每个句子中去掉了最后的标点符号,但你仍然知道句子是如何分开的(例如,可以把它们存储在一个数组中),这样就不会出现像won't这样意外分开的情况。

9

自然语言工具包(NLTK)可能正是你需要的工具。

>>> from nltk.tokenize import word_tokenize
>>> word_tokenize("'Hello. This is a test.  It works!")
["'Hello", '.', 'This', 'is', 'a', 'test', '.', 'It', 'works', '!']
>>> word_tokenize("I won't fix your computer")
['I', 'wo', "n't", 'fix', 'your', 'computer']

nltk.tokenize.word_tokenize 默认使用的是TreebankWordTokenizer,这是一种可以把句子拆分成单词的工具,它遵循的是宾夕法尼亚树库的规则。

需要注意的是,这个工具假设你的文本已经被分成了句子。

你可以在这个页面上测试NLTK提供的各种拆分工具(比如WordPunctTokenizerWhitespaceTokenizer等)。

撰写回答