Skip to content

Instantly share code, notes, and snippets.

@kbaribeau
Created July 24, 2011 21:06
Show Gist options
  • Save kbaribeau/1103102 to your computer and use it in GitHub Desktop.
Save kbaribeau/1103102 to your computer and use it in GitHub Desktop.
Ruby single quote escaping madness
Ok, so I'm trying to replace a ' character with \' in a ruby string. I have working code, but it was
*way* too painful getting there for my taste.
Take a look:
ree-1.8.7-2010.02 :001 > single_quote = "\'"
=> "'"
ree-1.8.7-2010.02 :003 > single_quote.gsub(/'/, "\\\'")
=> ""
ree-1.8.7-2010.02 :004 > single_quote.gsub(/'/) {|c| "\\'"}
=> "\\'"
I really expected my second attempt to work. I'm annoyed that I had to resort to using the block form
of gsub.
I think I understand a little bit about what's going on, I'll try to work it out here.
In the second argument (ie: the replacement string) ruby allows you to use backreferences.
ree-1.8.7-2010.02 :017 > "asdf".gsub(/(a)/, "\\0\\0")
=> "aasdf"
ree-1.8.7-2010.02 :018 > "asdf".gsub(/(a)/, '\\0\\0')
=> "aasdf"
ree-1.8.7-2010.02 :019 >
Actually, I was really surprised that works with both types of quotes... I didn't expect that.
Anyway, this means that in order to have a literal backslash in the replacement string, it must be
escaped (or else ruby will thing it's an indicator of a backreference). Since backslashes are escaped
anyway, I have to double escape them:
ree-1.8.7-2010.02 :025 > "asdf".gsub(/(a)/, "\\")
=> "\\sdf"
ree-1.8.7-2010.02 :026 >
(Don't be confused, that's actually ONE backslash in the output, irb just prints it twice)
I guess that means four blackslashes ought to do it:
ree-1.8.7-2010.02 :037 > "'".gsub(/'/, "\\\\'")
=> "\\'"
ree-1.8.7-2010.02 :038 >
Looks good; but the block form is more readable.
Interestingly, if I wanted to replace a backslash with an escaped backslash (ie: two backslashes), I would
have needed *eight* backslashes in the replacement string. That's just ridiculous.
Sometimes, ruby is a very hard language to love.
@chumakoff
Copy link

Thanks man! You saved my day! (and night)

@kbaribeau
Copy link
Author

Oh wow! That's wild. This gist is 12 years old! I'm glad it helped!

@rbuckheit
Copy link

another one saved in year 13, thank you! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment