Python 通过它的 readline 绑定可以实现出色的命令行自动完成(如 这里).

但是,补全似乎只在字符串的开头起作用。如果你想匹配字符串的中间或末尾,readline 不起作用。

我想在命令行 python 程序中通过将我输入的内容与可用字符串列表中的任何字符串进行匹配来自动完成字符串。

  • 我想要的自动完成类型的一个很好的例子是当您在“收件人”字段中键入时在 GMail 中发生的类型。如果您输入某个联系人的姓氏,该姓氏就会像您输入她的名字一样显示出来。
  • 可能需要使用向上和向下箭头或其他方法来从匹配的字符串中进行选择(在 readline 的情况下不需要),这对我来说没问题。
  • 我的特定用例是发送电子邮件的命令行程序。
  • 具体的代码示例会非常有帮助。

使用像curses这样的终端模拟器就可以了。它只需在 Linux 上运行,而不需要在 Mac 或 Windows 上运行。

这是一个例子:假设我的列表中有以下三个字符串

['Paul Eden <paul@domain.com>', 
'Eden Jones <ejones@domain.com>', 
'Somebody Else <somebody@domain.com>']

我想要一些代码,在输入“Eden”后自动完成列表中的前两项,然后允许我选择其中一项(全部通过使用键盘的命令行)。

有帮助吗?

解决方案

我不确定我是否理解这个问题。您可以使用 readline.clear_history 和 readline.add_history 设置所需的可完成字符串,然后使用 control-r 在历史记录中搜索后台词(就像在 shell 提示符下一样)。例如:

#!/usr/bin/env python

import readline

readline.clear_history()
readline.add_history('foo')
readline.add_history('bar')

while 1:
    print raw_input('> ')

或者,您可以编写自己的完整版本并将适当的密钥绑定到它。此版本使用缓存,以防您的匹配列表很大:

#!/usr/bin/env python

import readline

values = ['Paul Eden <paul@domain.com>', 
          'Eden Jones <ejones@domain.com>', 
          'Somebody Else <somebody@domain.com>']
completions = {}

def completer(text, state):
    try:
        matches = completions[text]
    except KeyError:
        matches = [value for value in values
                   if text.upper() in value.upper()]
        completions[text] = matches
    try:
        return matches[state]
    except IndexError:
        return None

readline.set_completer(completer)
readline.parse_and_bind('tab: menu-complete')

while 1:
    a = raw_input('> ')
    print 'said:', a
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top