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

时间:2012-12-10 08:23:37

标签: ruby escaping

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

我看到删除显然映射到ASCII 127,即Hex 7F,但是代码如下:

puts "a\x08b\x7fcd"

产生

b⌂cd

我希望\ x7f会删除它后面的'c'字符,但它不会。

4 个答案:

答案 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接口。见

Best gem for working with ncurses and 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'