On Jan 25, 2010, at 12:00 PM, lalawawa wrote:
=> “Can\1t we\1”
irb(main):005:0> a.gsub(/(['?])/, ‘\\\1’)
=> “Can\'t we\?”
(Well, Mike’s answer steals my thunder a bit, but I’ll put this out
there for anyone else that finds this thread.)
You just have to remember that there’s two levels of confusion, uh, I
mean escaping going on here.
Within single-quoted strings, the only backslash-escape is for a ’
and, so you can have a , you also need to escape the escape character:
‘\1’ means a backslash and a digit (because the character following
the \ is not ’ or \ it doesn’t have its special meaning)
‘\1’ means an escaped backslash and a digit (yes, the same as above,
but this time the first \ escapes the second \ so that it is
interpreted literally)
‘\\1’ means an escaped backslash, a backslash, and a digit (you see
where this is going, right?)
Now, within the replacement string for a gsub, you can have a
backslash-digit to mean “the n-th parenthesized group where the digit
is n”
So you want to replace with “a backslash and a backslash-digit for the
first group”. You need the final interpretation of the replacement to
end up as \ \1 (no quotes here to confuse things)
‘\’ is a literal
‘\\’ is a literal \ so gsub will see a real
‘\1’ is \1 because 1 isn’t a special character
SO…
‘\\\1’ is seen as \\1 (as the argument) and gsub interprets it as
“literal backslash, first group”
‘\\\1’ is seen the same way; the fifth backslash escapes the sixth,
then the 1
You might consider using the block form of gsub replacement.
irb> a = “Can’t we?”
=> “Can’t we?”
irb> a.gsub(/([‘?])/, ‘\\\1’)
=> “Can\'t we\?”
irb> puts _
Can't we?
=> nil
irb> a.gsub(/[’?]/) {|m| ‘\’ + m}
=> “Can\'t we\?”
irb> puts _
Can't we?
=> nil
In your case, the clarity that results from the simplification of the
replacement should be obvious.
-Rob
Rob B. http://agileconsultingllc.com
[email protected]