Bug #21651
closedreplacing a string with one backslash with two backslashes
Description
ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [x86_64-linux]
ruby 3.4.4 (2025-05-14 revision a38531fd3f) +PRISM [x86_64-linux]
irb(main):002> "\\".gsub("\\", "\\\\")
=> "\\"
irb(main):003> "\\".gsub("\\", "\\ \\")
=> "\\ \\"
The replacement is happening, as you can see from the version with the space, but why is the result so strange without the space?
Similar code works fine in JS:
"\\".replace("\\", "\\\\")
> '\\\\'
How to replace one backslash with two backslashes?
Updated by nobu (Nobuyoshi Nakada) about 12 hours ago
- Status changed from Open to Feedback
From String@Substitution+Methods:
Note that \\ is interpreted as an escape, i.e., a single backslash.
Note also that a string literal consumes backslashes.
See String Literals for details about string literals.
This is what happens at the first line.
Since a space after a backslash is not a valid escape, the result at the second line is "\ \".
If you want to write a non-back-reference string & in
replacement, you need to first escape the backslash to prevent
this method from interpreting it as a back-reference, and then you
need to escape the backslashes again to prevent a string literal from
consuming them: "..\\\\&..".
For your example:
"\\".gsub("\\", "\\\\\\\\") # literally two backslashes
"\\".gsub("\\", "\\&\\&") # double the matched substrings
"\\".gsub("\\") {"\\\\"} # the block result used literally