如何在Ruby中安全可逆地转义字符串引号?

5

请问 Ruby 中与 Python 字符串的 encode('string_escape')decode 函数 等价的函数是什么?

在 Python 中,我可以这样做:

>>> s="this isn't a \"very\" good example!"
>>> print s
this isn't a "very" good example!
>>> s
'this isn\'t a "very" good example!'
>>> e=s.encode('string_escape')
>>> print e
this isn\'t a "very" good example!
>>> e
'this isn\\\'t a "very" good example!'
>>> d=e.decode('string_escape')
>>> print d
this isn't a "very" good example!
>>> d
'this isn\'t a "very" good example!'

如何在Ruby中实现相同的功能?
3个回答

1

可能是inspect

irb(main):001:0> s="this isn't a \"very\" good example!"
=> "this isn't a \"very\" good example!"
irb(main):002:0> puts s
this isn't a "very" good example!
=> nil
irb(main):003:0> puts s.inspect
"this isn't a \"very\" good example!"

请注意,解码要复杂得多,因为inspect也会转义任何非UTF-8文件中有效的内容(如二进制),所以如果您知道除了有限子集之外永远不会有其他任何东西,请使用gsub。然而,将其转换回字符串的唯一真正方法是通过解析它,可以从您自己的解析器或使用eval实现:
irb(main):001:0> s = "\" hello\xff I have\n\r\t\v lots of escapes!'"
=> "\" hello\xFF I have\n\r\t\v lots of escapes!'"
irb(main):002:0> puts s
" hello� I have

         lots of escapes!'
=> nil
irb(main):003:0> puts s.inspect
"\" hello\xFF I have\n\r\t\v lots of escapes!'"
=> nil
irb(main):004:0> puts eval(s.inspect)
" hello� I have

         lots of escapes!'
=> nil

显然,如果你不是在做inspect,那么不要使用eval,编写自己的/找到一个解析器,但如果你是在调用inspect之前立即调用eval并且s保证是一个字符串(s.is_a? String),那么它是完全安全的。


谢谢你的回答!看起来这就是我需要的编码,那解码呢? - FriendFX
1
string.gsub(/\\"/, '"') 可能吗?这太琐碎了,实际上没有任何内置方法。 - tadman
好的,eval确实是唯一的方法来获取返回值,因为它可以转义非打印二进制。 - byteit101
1
@byteit101,这听起来有点危险,类似于使用JavaScript的eval()来获取JSON编码数据?我也不希望出现不可打印的二进制,但几乎可以接受任何其他类型的数据。 - FriendFX
也许你或者@tadman可以将eval和/或gsub解决方案结合起来,为我提供一个完整的答案,包括解码,这样我就可以接受了? - FriendFX
2
在这里,eval绝对不是你想要的东西。 - tadman

1
好的,翻译如下:

那么,你可以这样做:

'string"and"something'.gsub '"', '\"'

0

我不知道这是否相关,但如果我想避免处理转义,我只需使用%q[ ]语法。

s = %q[this isn't a "very" good example!]
puts s
p s

会给予

'this isn't \ a "very" good example!'
"'this isn't \\ a \"very\" good example!'"

谢谢您的回答,但是针对我的使用情况,我需要处理用户提供的字符串,所以那不是一个选项。 - FriendFX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接