I am not getting why
puts("whit'e bread".gsub("'","\\\'"))
is giving result as
white breade bread
I was hoping end result should be
whit\'e bread
I am not getting why
puts("whit'e bread".gsub("'","\\\'"))
is giving result as
white breade bread
I was hoping end result should be
whit\'e bread
The documentation of String#sub
explains:
If replacement is a String that looks like a pattern's capture group but is actually not a pattern capture group e.g. "\'", then it will have to be preceded by two backslashes like so "\\'".
But $'
is a global variable whose meaning is "The string to the right of the last successful match." and \'
in a replacement string has the same meaning.
Now, back to your replacement string, let's remember that in string literals, the backslash (\
) is a special character that introduces an escape sequence. In order to represent itself, the backslash must be represented as \\
.
Now everything is clear. The replacement string "\\\'"
represents a backslash (\\
) followed by the escape sequence \'
that represents a single quote character ('
).
(In double quoted string literals, there is no need to escape the single quote characters but the backslash in front of them doesn't change the result; in single quote string literals it is required to use the escape sequence \'
to encode a single quote character, otherwise it is the marker of the end of string.)
By combining all said above:
"whit'e bread".gsub("'","\\\'")
replaces the single quote with \'
which is e bread
(the string to the right of the last successful match) and the result is white breade bread. (The replacement string is displayed in bold letters.)
In order to get the expected result you have to use \\'
as the replacement string. The correct way to write it in code as a string literal is "\\\\'"
. The code becomes:
"whit'e bread".gsub("'","\\\\'")
and it produces the expected result.
The documentation of String#gsub
in Ruby 2.7.0 is more descriptive and clearly says:
Similarly,
\&
,\'
,\`
, and+
correspond to special variables,$&
,$'
,$`
, and$+
, respectively. (See regexp.rdoc for details.)
Thanks to @sergio-tulentsev for the links he used in his answer.