在Ruby中最好的方法来逃避和unescapestring?

Ruby是否有任何内置的方法来转义转义string? 在过去,我使用正则expression式; 然而,我发现Ruby可能会一直在内部进行这样的转换。 也许这个function暴露在某个地方。

到目前为止,我已经提出了这些function。 他们工作,但他们似乎有点hacky:

def escape(s) s.inspect[1..-2] end def unescape(s) eval %Q{"#{s}"} end 

有没有更好的办法?

如果您不想使用eval ,但愿意使用YAML模块,则可以使用它:

 require 'yaml' def unescape(s) YAML.load(%Q(---\n"#{s}"\n)) end 

YAML优于eval的优势在于它可能更安全。 cane不允许使用eval 。 我已经看到了使用$SAFEeval ,但目前尚不能通过JRuby获得。

对于什么是值得的,Python确实对反斜杠进行了原生支持。

有一些逃避方法,其中一些:

 # Regexp escapings >> Regexp.escape('\*?{}.') => \\\*\?\{\}\. >> URI.escape("test=100%") => "test=100%25" >> CGI.escape("test=100%") => "test%3D100%25" 

所以,这要看你需要解决的问题。 但我会避免使用检查逃脱。

更新 – 有一个转储,检查使用,它看起来就是你所需要的:

 >> "\n\t".dump => "\"\\n\\t\"" 

Caleb函数是最接近的String #inspect相反我能find,但它包含两个错误:

  • \\处理不当。
  • \ x ..保留了反斜杠。

我修复了上面的错误,这是更新后的版本:

 UNESCAPES = { 'a' => "\x07", 'b' => "\x08", 't' => "\x09", 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c", 'r' => "\x0d", 'e' => "\x1b", "\\\\" => "\x5c", "\"" => "\x22", "'" => "\x27" } def unescape(str) # Escape all the things str.gsub(/\\(?:([#{UNESCAPES.keys.join}])|u([\da-fA-F]{4}))|\\0?x([\da-fA-F]{2})/) { if $1 if $1 == '\\' then '\\' else UNESCAPES[$1] end elsif $2 # escape \u0000 unicode ["#$2".hex].pack('U*') elsif $3 # escape \0xff or \xff [$3].pack('H2') end } end # To test it while true line = STDIN.gets puts unescape(line) end 

YAML的::unescape似乎没有逃避引号字符,例如'" 。我猜这是devise,但这让我伤心。

你绝对不想在任意或客户端提供的数据上使用eval

这是我用的。 处理我见过的所有东西,不会引入任何依赖关系。

 UNESCAPES = { 'a' => "\x07", 'b' => "\x08", 't' => "\x09", 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c", 'r' => "\x0d", 'e' => "\x1b", "\\\\" => "\x5c", "\"" => "\x22", "'" => "\x27" } def unescape(str) # Escape all the things str.gsub(/\\(?:([#{UNESCAPES.keys.join}])|u([\da-fA-F]{4}))|\\0?x([\da-fA-F]{2})/) { if $1 if $1 == '\\' then '\\' else UNESCAPES[$1] end elsif $2 # escape \u0000 unicode ["#$2".hex].pack('U*') elsif $3 # escape \0xff or \xff [$3].pack('H2') end } end 

Ruby的inspect可以帮助:

  "a\nb".inspect => "\"a\\nb\"" 

通常情况下,如果我们打印一个embedded式换行的string,我们会得到:

 puts "a\nb" a b 

如果我们打印检查版本:

 puts "a\nb".inspect "a\nb" 

将检查的版本分配给一个variables,并且你将得到该string的转义版本。

要撤销转义,请evalstring:

 puts eval("a\nb".inspect) a b 

我真的不喜欢这样做。 这比我在实践中要做的事情更加好奇。