有没有Python库用于自定义自动补全?

3 投票
2 回答
3400 浏览
提问于 2025-04-16 22:21

有没有一个通用的库,可以让我根据自定义的语法和物品列表来实现自动补全功能?

下面是我想要的一个例子。

语法:

  • 你可以吃苹果和芒果
  • 你可以喝牛奶和水
  • 你可以移动所有东西
  • 句子结构:动词 [+ 形容词] + 宾语

物品:

  • 1个绿色苹果
  • 1个微型苹果
  • 1个绿色芒果
  • 1个黄色芒果
  • 1个芒果 [没有颜色]
  • 1瓶牛奶
  • 1瓶水

预期的行为(用户在第一行输入,第二行显示建议)

m
move, munch

mo
move

move g
move green apple, move green mango

move y
move yellow mango

move m
move milk, move mango, move microscopic apple

2 个回答

2

我知道的一个可以自动补全的模块是Qt的QCompleter,你可以通过PyQt或PySide在Python中使用它。我觉得它并不完全理解你所说的语法,但它的功能比较通用,可以让你编写代码来实现这个功能。

2

我终于找到了一种可以接受的解决方案,使用了SPARK(用于语法解析和句法分析)和我自己写的代码来实现自动补全。

关于 SPARK

SPARK 是“扫描、解析和重写工具包”的缩写。它之前没有名字,大家称它为“小语言框架”。第一个版本(大约在1998年)在第七届国际Python大会上发表的论文中被描述,论文标题是用Python编译小语言

SPARK 完全用纯Python编写,并且是开源的。

自动补全代码

在下面的代码中:

  • category 是我们要进行自动补全的单词类型。这是通过解析当前的命令行获得的。例如:如果用户输入的是"drink m",解析器就会知道接下来要期待一个属于“液体”这个类别的单词。
  • 用户的输入会存储在一个列表中(self.chars
  • _get_list_of_existing() 会返回一个给定类别中已存在的单词列表
  • _get_common_beginning() 会返回 - 如果有的话 - 多个匹配项的最长共同前缀。例如,如果用户输入的是"ma",而可能的自动补全单词是[magnolia, magnifying glass],那么_get_common_beginning() 会返回"magn"

以下是相关的代码片段:

def autocomplete(self, category):
    '''
    If possible, autocomplete a word according to its category.
    '''
    root = ''.join(self.chars).split()[-1]  #The bit after the last space
    pool = self._get_list_of_existing(category)
    matches = [i for i in pool if i.find(root) == 0]
    if len(matches) == 1:
        match = matches[0]+' '
    elif len(matches) > 1:
        match = self._get_common_beginning(matches)
    else:
        return
    self.chars.extend(list(match[len(root):]))

def _get_common_beginning(self, strings):
    '''
    Return the strings that is common to the beginning of each string in
    the strings list.
    '''
    result = []
    limit = min([len(s) for s in strings])
    for i in range(limit):
        chs = set([s[i] for s in strings])
        if len(chs) == 1:
            result.append(chs.pop())
        else:
            break
    return ''.join(result)

撰写回答