读取线被ANSI转义序列混淆

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读取线被ANSI转义序列混淆相关的知识,希望对你有一定的参考价值。

我正在研究一个Python脚本,有时需要用户输入输入。我在macOS Sierra上使用bash。

为了接收输入,我写了以下内容:

import readline  # gnureadline 6.3.8

START = '33[91m33[1m'
END = '33[0m'

response = raw_input(START + 'Enter text: ' + END)

我在STARTEND中使用ANSI转义序列来直观地区分脚本的提示和用户的文本条目。

不幸的是,一旦我开始输入文本,程序就会丢失用户输入文本的开头实际所在的位置。下面的第一个克拉是CTRLA现在映射到的地方,第二个是CTRLE带我的地方。箭头键同样相信用户输入的开始和结束是偏移的,如图所示。

Enter text: hello my name is             
                         ^               ^  

我尝试了一些东西来调试这个。

  1. 我尝试在提示符和文本条目之间添加换行符,但这只会使偏移量变差。
  2. 如果我只使用箭头键并且从不使用CTRLA,CTRLE,选项箭头来浏览字符串,则按预期工作。也就是说,考虑到用户输入的字符串的长度和复杂性,仅使用箭头键移动字符串对用户来说将是痛苦的。
  3. 最重要的是,如果我根本不使用STARTEND,这种方法非常有效。也就是说,脚本的可用性下降了 - 很难从该脚本的完整版本中找到所有其他文本中的提示。

我是否有一些技巧可以使用ANSI转义序列格式化提示,而不会破坏用户使用CTRLA,CTRLE和选项箭头导航的能力?谢谢!

答案

单独打印提示并要求输入两个命令。

Python等

print(START + 'Enter text: ' + END, end='')
response = input()

Python 2.x

import sys

# Use sys.stdout.write to avoid printing a trailing newline.
sys.stdout.write(START + 'Enter text: ' + END)
response = raw_input()
另一答案

在我的情况下,接受的答案没有成功。

我开始了

START = 'x1b[7mx1b[37m' # white on black
END = 'x1b[0m'  # reset
response = input(START + 'QUERY ' + END)

这同样导致了

QUERY hello my name is hello my name is
              ^                                ^
              hello my name is hello my name is

使用上面的解决方案,

print(START + 'QUERY ' + END, end='')
response = input()

导致它考虑从一开始就开始的线

QUERY hello my name is hello my name is
^                                ^
hello my name is hello my name is

可能是因为input("")长0个字符。

知道那些控制字符被计为偏移量,我们可以再次使用它们来创建偏移量。

我的文字QUERY 长6个字符,所以我可以使用

print(START + 'QUERY ' + END, end='')
response = input('33[D33[C')

因为Cursor Forward, Cursor Back '33', '[', 'D''33', '[', 'C'欺骗readline抵消6个字符。

QUERY hello my name is hello my name is
[D[C^                                ^
      hello my name is hello my name is
另一答案

Readline期望0102作为隐形字符周围的标记:

import readline  # gnureadline 6.3.8

START = '0133[91m33[1m02'
END = '0133[0m02'

response = raw_input(START + 'Enter text: ' + END)

对于ANSI转义序列,前缀为01,后缀为02,GNU readline将知道在确定提示字符串的长度时应排除这些字符。

以上是关于读取线被ANSI转义序列混淆的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHP 将 ANSI 转义序列转换为 HTML

如何让 win32 控制台识别 ANSI/VT100 转义序列?

[C#, 笔记] 启用虚拟终端处理 (使用 ANSI 转义序列前需启用)

[C#, 笔记] 启用虚拟终端处理 (使用 ANSI 转义序列前需启用)

ANSI 颜色转义序列列表

ANSI 颜色转义序列字符出现在 String.length();