如何从凌乱的字符串中提取有意义的单词?

时间:2014-01-05 04:44:16

标签: python regex nlp

考虑如下字符串,如何提取任何有意义的单词?

ctl00_PD_lblProductTitle ---> 'Product Title' (ct100_PD_lbl is not a complete word, ignore)

prod-detail-info ---> 'Detail Info' (prod is not a complete word, ignore)

prodprice price-onsale ---> 'price on sale' (prod is not a complete word, ignore)

rating-score ---> 'Rating Score'

RatingScore ---> 'Rating Score' 

很想知道这个被调用的技术或过程以及任何库(如果有的话)。正则表达式足够强大吗?

2 个答案:

答案 0 :(得分:4)

简而言之,除非您将决策树或分类器倾斜到特定数据,否则无法按照您希望的方式评估您提供的示例。 (例如,考虑数字2和3. Prod是任何英语词典中的一个词,但是大多数英语词典中都不会显示信息。)

如果您在这些特定数据上训练分类器或决策树,那么您才能获得所需的结果。但一般来说,您可能会尝试将文本标记为开头(如@ user2314737建议的那样):

>>> import nltk
>>> t = '''ctl00_PD_lblProductTitle

prod-detail-info

prodprice price-onsale

rating-score

RatingScore'''
>>> nltk.tokenize.wordpunct_tokenize(t)
['ctl00_PD_lblProductTitle', 'prod', '-', 'detail', '-', 'info', 'prodprice', 'price', '-', 'onsale', 'rating', '-', 'score', 'RatingScore']

然后你可以用正则表达式找到更多可能的单词,例如:

>>> re.findall(r'[A-Z][a-z]{2,}', 'ctl00_PD_lblProductTitle')  # also works for 'RatingScore'
['Product', 'Title']

此正则表达式将查找以大写字母开头的所有序列,然后是2个或更多小写字母。关于你的评论,不,这个正则表达式不适用于unicode。不幸的是,Python中的正则表达式目前无法以相同的方式区分大写和小写。在这种情况下,你可能需要这样的东西(我很快就把它扔在一起而不花时间把它弄得很漂亮):

>>> def split_at_uppercase(text):
    result = []
    new_word = []
    for char in text:
        if char.isupper():
            if new_word:
                result.append(''.join(new_word))
            new_word = []
            new_word.append(char)
        elif new_word and char == ' ':  # in more complicate scenarios, may need to use regex for white space
            result.append(''.join(new_word))
            new_word = []
        elif char != ' ':
            new_word.append(char)
    else:
        result.append(''.join(new_word))
    return result

>>> t = 'καὶ τοῦΠιλάτου εἰςἹεροσόλυμα'
>>> split_at_uppercase(t)
['καὶ', 'τοῦ', 'Πιλάτου', 'εἰς', 'Ἱεροσόλυμα']

然后,正如@acarlon建议的那样,您将开始需要检查字典中的子字符串(例如PyEnchant)。但即便如此,你会发现'意思是'没有人可能意图传授它。此外,您将发现您不感兴趣的单词(例如prod)。

答案 1 :(得分:0)

我建议:

  1. 提取所有单词(字母序列 - 这将包括诸如ProductTitle之类的复合单词),即将所有不是字母的内容删除到组中。正则表达式类似于([a-zA-Z])+?)+?表示非贪婪。
  2. 对于每个单词,在英语词典数据库中查找单词。如果有匹配,则转到下一个单词。如果没有,请转到第3步。
  3. 如果不匹配,则尝试在复合词中找到多个单词,例如ProductTitle - >产品名称。这不是一项简单的任务,需要一个决策树类型的操作和回滚的能力。请查看triesthis answer