Ruby 删除下一个/尾随字符的转义序列?

Ruby 删除下一个/尾随字符的转义序列?,ruby,escaping,Ruby,Escaping,除了使用\x08删除前导字符外,是否还可以删除尾随字符?是否存在将删除下一个字符而不是上一个字符的转义序列 我看到delete显然映射到ASCII 127,即十六进制7F,但以下代码: puts "a\x08b\x7fcd" 产生 b⌂cd 我原以为\x7f会删除它后面的“c”字符,但它没有删除。您实际上并没有用\x08删除任何内容,您只是用“b”覆盖了“a” 想象一下过去你使用电传打字纸终端的情景。实际上,你会在纸上看到一个“a”字,电传打字机会备份一个空格,然后在上面打印一个“b”。所有

除了使用
\x08
删除前导字符外,是否还可以删除尾随字符?是否存在将删除下一个字符而不是上一个字符的转义序列

我看到delete显然映射到ASCII 127,即十六进制7F,但以下代码:

puts "a\x08b\x7fcd"
产生

b⌂cd

我原以为\x7f会删除它后面的“c”字符,但它没有删除。

您实际上并没有用
\x08
删除任何内容,您只是用“b”覆盖了“a”

想象一下过去你使用电传打字纸终端的情景。实际上,你会在纸上看到一个“a”字,电传打字机会备份一个空格,然后在上面打印一个“b”。所有非印刷ascii码都是为了控制电传打字纸终端的移动而发明的

这正是上面的输出所做的,只有终端屏幕不会为前一个“a”保持像素点亮

“del”字符对基本终端屏幕没有这种特殊意义。它对程序(如编辑器或shell)可能意味着什么,但对标准输出来说,它只是另一个要打印的ascii字符

“del”的原意是忽略此字符作为输入,请参见:

据我所知,没有什么可以放在字符之前,STDOUT会将其视为不打印下一个字符的信号。然而,如果您的输出是一个终端仿真程序,比如xterm,那么您可以使用转义码来完成许多事情。例如,见:

提取所有这些复杂代码的“标准”库是
ncurses
,其中有两个ruby接口。看

退格字符(charcode
?\x08
、别名
?\b
及其频繁的
?\C-H
(Ctrl+H)映射)与删除字符(charcode
?\x7f
,表示ascii 127)不同。开箱即用,两者之间的区别在于,在删除之前,退格将光标位置向左移动

请注意,在unix平台上的这两种情况下,deleting通常表示kill-escape序列,后者表示从光标右侧终止该行(例如,与Terminal中的Ctrl+K映射类似)。换句话说,
?\b
相当于
“\e[D\e[K”
(左,kill)和
?\x7f
相当于
“\e[K”
(kill)。IRB(Ruby 2.0.0,OSX)中的示例输出说明了这一点:

>> 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
上面的操作字通常是。如果在终端中使用getch,其行为将与IRB的行为完全不同。(如果内存可用,则delete键将向左移动字符,而不会终止行,或按该顺序执行操作。)

回到你的问题,澄清一下:据我所知,没有在光标位置杀死单个字符的转义序列;只有在光标左侧、右侧或两侧杀死一行的序列。Fred发布的参考非常好,以防你想深入:

无论如何,我猜你是在玩
getch
或类似的东西。为了删除单个字符,你要做的是在将字符打印到标准输出的同时保持缓冲区和光标的位置。这将允许你映射
?\b
?\x7f
,如你所见它可以使用以下方法:

def refresh
  rest = @buffer[@position..-1]
  @stdout.print "\e[K"
  @stdout.print rest, "\e[#{rest.length}D" if rest && !rest.empty?
  nil
end

或者,尝试一下常见的疑点,让自己免于头疼:readline、ncurses、highline gem等等。

这里的主要问题是:标准
IO
没有短期内存。这意味着没有神奇的操作实体来处理即将出现的符号。下面的代码片段显示“delete,”即使配备了a,也不知道未来的符号:

> puts "a#{`tput dch1`}b"
# ⇒ ab
无论您是否真的需要“删除预期符号”,我建议您使用纯ruby monkeypatch:

class String
  DEL = '␡'
  def postprocess
    self.gsub /#{DEL}./, ''
  end
end

puts "a␡bc".postprocess
# ⇒ ac

实际上,这并不是对您的问题的直接回答,但它可能会给出一个建议。

以下是删除下一个字符的另一种方法:

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'

echo-e1'first\e7second\e8\e[knowed'
#使用保存光标位置和恢复光标位置awesome链接@fred the magic wonder dog=>输出firstnew,比