Created
July 24, 2011 21:06
-
-
Save kbaribeau/1103102 to your computer and use it in GitHub Desktop.
Ruby single quote escaping madness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
Oh wow! That's wild. This gist is 12 years old! I'm glad it helped!
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
Thanks man! You saved my day! (and night)