On 04.01.2017 19:47, niemda wrote:
How do I properly convert ruby string into backslash-escaped string? The source is base64-encoded value and result should be escaped, so some charaters must be encoded as '\xnn'.
Example:
Input is 'tracking@c3BlYw==.service' and expected result
is 'tracking@c3BlYw\x3d\x3d.service'.
I've already invented the wheel by hacking some conversion routine to do
this and tried eval (not in production code, the problem mainly exists
in specs).
I have no idea why someone would need to use eval() to implement this.
Here's a fairly straightforward approach:
CONVERSIONS = {
"=" => "\\x3d",
}
def CONVERSIONS.apply(s)
s.each_char.map {|ch| self[ch] || ch}.join
end
irb(main):010:0> CONVERSIONS.apply 'tracking@c3BlYw==.service'
"tracking@c3BlYw\\x3d\\x3d.service"
Note that the double backslashes are an artifact of the way #inspect
works. There are just single backslashes in the string.
irb(main):011:0> puts CONVERSIONS.apply 'tracking@c3BlYw==.service' tracking@c3BlYw\x3d\x3d.service
nil
You can also do
def CONVERSIONS.apply(s)
s.gsub(Regexp.union(keys)) {|ch| self[ch]}
end
irb(main):016:0> CONVERSIONS.apply 'tracking@c3BlYw==.service'
"tracking@c3BlYw\\x3d\\x3d.service"
Although this is slightly inefficient since the Regexp does not change
as long as the Hash does not change. This could be remedied by freezing
the Hash and storing the Regexp in another constant or member of
CONVERSIONS. Or you can use a fixed regex
def CONVERSIONS.apply(s)
s.gsub(/./) {|ch| self[ch] || ch}
end
Here's another variant:
def CONVERSIONS.apply(s)
s.each_char.inject("") {|str, ch| str << (self[ch] || ch)}
end
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)