除了使用\x08
删除前导字符外,是否还可以删除尾随字符?是否有一个转义序列将删除下一个字符而不是前一个字符?
我看到删除显然映射到ASCII 127,即Hex 7F,但是代码如下:
puts "a\x08b\x7fcd"
产生
b⌂cd
我希望\ x7f会删除它后面的'c'字符,但它不会。
答案 0 :(得分:6)
你实际上并没有用\x08
删除任何内容,而只是用“b”覆盖“a”。
想象一下你使用电传纸质终端的旧时代。您在纸上实际看到的是“a”打印,电传打字机将备份一个空格,然后在其上打印“b”。所有非打印ascii代码都是为了控制电传纸终端的移动而发明的。
这正是上面的输出,只有终端屏幕不会保持前一个“a”的像素点亮。
“del”char对基本终端屏幕没有这种特殊含义。它可能对程序(如编辑器或shell)有意义,但对于STDOUT来说,它只是打印的另一个ascii char。
“del”的原始含义是忽略此char作为输入,请参阅:
http://en.wikipedia.org/wiki/Delete_character
我不知道你可以把它放在一个字符之前,STDOUT将把它视为不打印下一个CHAR的信号。但是,如果你的输出是终端仿真程序,如xterm,你可以使用转义码做很多事情来完成你想要的。例如见:
http://ascii-table.com/ansi-escape-sequences-vt-100.php
用于抽象出所有这些复杂代码的“标准”库是ncurses
,其中有几个ruby接口。见
答案 1 :(得分:2)
这里的主要问题是:标准IO
没有短期记忆。这表明没有神奇的操作实体可以对即将推出的符号采取行动。以下代码段显示“删除”,即使提供modern way,也不知道未来的符号:
> puts "a#{`tput dch1`}b"
# ⇒ ab
你是否真的需要“删除预期符号”,我建议你使用普通红宝石monkeypatch:
class String
DEL = '␡'
def postprocess
self.gsub /#{DEL}./, ''
end
end
puts "a␡bc".postprocess
# ⇒ ac
实际上,这不是您问题的直接答案,但可能会提出建议。
答案 2 :(得分:1)
退格符(charcode ?\x08
,其别名?\b
及其频繁?\C-H
(Ctrl + H)映射)与删除字符(charcode {{1})不同},意思是ascii 127)。开箱即用,两者之间的区别在于退格会在删除之前将光标位置向左移动。
请注意,在unix平台的两种情况下,删除通常代表kill escape序列,后者代表从光标右侧删除该行(即类似于Terminal中的Ctrl + K映射)。换句话说,?\x7f
相当于?\b
(左,杀),"\e[D\e[K"
相当于?\x7f
(杀戮)。 IRB(Ruby 2.0.0,OSX)中的示例输出说明了这一点:
"\e[K"
上面的操作词通常是 。如果您在终端中使用getch,则行为将与IRB的行为完全不同。 (如果内存服务,则删除键将移动该字符而不会删除该行,或该命令的某些内容。)
回到你的问题澄清:据我所知,没有转义序列来杀死光标位置的单个字符;只有序列才能杀死光标左侧,右侧或两侧的一条线。弗雷德发布的参考资料非常好,以防你想潜入:
http://ascii-table.com/ansi-escape-sequences-vt-100.php
无论如何,我猜你正在玩>> print "abc\b" # abc, backspace
ab=> nil
>> print "abc\e[D\b" # abc, left, backspace
a=> nil
>> print "abc\x7f" # abc, delete
abc=> nil
>> print "abc\e[D\x7f" # abc, left, delete
ab=> nil
>> print "abc\e[D\e[D\x7f" # abc, left, left, delete
a=> nil
>> print "abc\e[D\e[D\e[K" # abc, left, left, kill
a=> nil
或者那个订单。为了删除单个字符,您想要做的是在将字符打印到stdout的同时保持缓冲区和光标的位置。这样您就可以使用以下内容映射getch
或?\b
,如下所示:
?\x7f
或者,尝试通常的嫌疑人,以避免头痛:readline,ncurses,highline gem等。
答案 3 :(得分:0)
这是删除下一个字符的另一种方法:
class String
alias_method :default_initialize, :initialize
alias_method :default_plus, :+
attr_accessor :delnext
def initialize
default_initialize
@delnext = false
end
def +(x)
str = String(x)
str[0] = '' if @delnext
@delnext = false
default_plus str
end
end
现在,你可以这样做:
s = 'test string'
s.delnext = true
s += 'test again'
s # => 'test stringest again'
同样,您可以轻松实现delprev
:
class String
def delprev
self[self.length - 1] = ''
# self # uncomment if you want delprev to return the new string
end
end
s = 'test string'
s.delprev
s # => 'test strin'