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\xfor 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