11:20 pm, 14 Nov 06
ruby wart: escaping apostrophes
Suppose I wanna escape all apostrophes with a backslash.
1.
2.
3.
4.
The best way to do it?
Yuck.
1.
"a'b".gsub(/'/, "\'") ⇒ "a'b"
— doesn't work, as \' evaluates to ' in double quotes)2.
"a'b".gsub(/'/, "\\'") ⇒ "abb"
— \' is special for gsub (!!!)3.
"a'b".gsub(/'/, "\\\'") ⇒ "abb"
— by #1, the \' expands into the same string as #24.
"a'b".gsub(/'/, "\\\\'") ⇒ "a\\'b"
— this works, but ew. And it's not even clear to me why it works. (The output looks wrong but remember Ruby is pretty-printing the single \ as \\ in the output.)The best way to do it?
"a'b".gsub(/'/){"\\'"} ⇒ "a\\'b"
Yuck.
Ruby escaping
The answer why 4 works is, presumably, that there are two levels of unescaping going on before the string is used as replacement text. I've not used Ruby, but it would appear that the first one is in parsing the double quoted string (which eats the first of each pair of \s), and the second is as suggested by example 2 (ie, that \' is a special case).If Ruby follows the Perl (and Bourne shell, etc) convention that double quoted strings are subject to unescaping/expansion/interpolation/etc, and single quoted strings are not, then that may offer you a solution. Although you'd probably need something like Perl's q() operator (which acts as a single quoted string, but with your choice of terminators) to avoid conflicts with the literal ' that you want to include. OTOH your "tidy" solution is a fairly reasonable approach too, for the specific problem.
Ewen
Re: Ruby escaping
Unfortunately, as far as I can tell all of Ruby's quote operators (which include single quotes and %q which is like Perl's) still interpret \' and \\."a'b".gsub(/(?=')/, "\\")
⇒ "a\\'b"