Consider the following snippet:
puts 'hello'.gsub(/.+/, '\0 \\0 \\\0 \\\\0')
This prints (as seen on ideone.com):
hello hello \0 \0
This was very surprising, because I'd expect to see something like this instead:
hello \0 \hello \\0
My argument is that \
is an escape character, so you write \\
to get a literal backslash, thus \\0
is a literal backslash \
followed by 0
, etc. Obviously this is not how gsub
is interpreting it, so can someone explain what's going on?
And what do I have to do to get the replacement I want above?
Escaping is limited when using single quotes rather then double quotes:
"\0"
is the null-character (used i.e. in C to determine the end of a string), where as'\0'
is"\\0"
, therefore both'hello'.gsub(/.+/, '\0')
and'hello'.gsub(/.+/, "\\0")
return"hello"
, but'hello'.gsub(/.+/, "\0")
returns"\000"
. Now'hello'.gsub(/.+/, '\\0')
returning'hello'
is ruby trying to deal with programmers not keeping the difference between single and double quotes in mind. In fact, this has nothing to do withgsub
:'\0' == "\\0"
and'\\0' == "\\0"
. Following this logic, whatever you might think of it, this is how ruby sees the other strings: both'\\\0'
and'\\\\0'
equal"\\\\0"
, which (when printed) gives you\\0
. As gsub uses\x
for inserting match number x, you need a way to escape\x
, which is\\x
, or in its string representation:"\\\\x"
.Therefore the line
indeed results in