From: Robert Klemme Date: 2010-11-22T22:53:02+09:00 Subject: Re: gsub and backslashes On Mon, Nov 22, 2010 at 1:28 PM, Ammar Ali wrote: > On Mon, Nov 22, 2010 at 10:38 AM, Robert Klemme > wrote: >> On Mon, Nov 22, 2010 at 12:27 AM, Ammar Ali wrote: >>> On Sun, Nov 21, 2010 at 11:02 PM, Brian Candler wrote: >>>> Ralph Shnelvar wrote in post #962847: >>>>>   "\\1\\2\\3".gsub(/\\/,"\\\\") >>>> >>>> Here you are replacing one backslash with one backslash. >>>> >>>> The trouble is, in the *replacement* string, '\1' has a special meaning >>>> (insert the value of the first capture). Because of this, a literal >>>> backslash is backslash-backslash. >>> >>> That's a keen observation, but the fact that they happen to be >>> back-references doesn't seem to play a part in this situation. >>> >>>>> "\\a\\b\\c".gsub(/\\/,"\\\\") >>> => "\\a\\b\\c" >>>>> "\\a\\b\\c".gsub(/\\/,"\\\\\\") >>> => "\\\\a\\\\b\\\\c" >> >> The key point to understand IMHO is that a backslash is special in >> replacement strings.  So, whenever one wants to have a literal >> backslash in a replacement string one needs to escape it and hence >> have to backslashes.  Coincidentally a backslash is also special in a >> string (even in a single quoted string).  So you need two levels of >> escaping, makes 2 * 2 = 4 backslashes on the screen for one literal >> replacement backslash. > > Actually, 3 backslashes will yield one backslash. The first two result > in one (escaped), and the third one, escaped by the previous escaped > backslash ends up being one. My second example showed this, using 6 > backslashes instead of 8. Using 4 backslashes works because the second > pair yields and escaped backslash, but it is not necessary. That does not work reliably under all circumstances though: irb(main):006:0> "abc".gsub /./, "\\\n" => "\\\n\\\n\\\n" irb(main):007:0> puts("abc".gsub /./, "\\\n") \ \ \ => nil irb(main):008:0> "abc".gsub /./, "\\\\n" => "\\n\\n\\n" irb(main):009:0> puts("abc".gsub /./, "\\\\n") \n\n\n => nil It is safer to use 4 backslashes. This is the only robust way to do this even though sometimes you can simply use a single backslash (e.g. \1 instead of \\1) because string parsing is a bit tolerant under some circumstances: irb(main):014:0> '\1' => "\\1" irb(main):015:0> '\\1' => "\\1" but irb(main):019:0> "\n" => "\n" irb(main):020:0> "\\n" => "\\n" irb(main):021:0> "\1" => "\x01" irb(main):022:0> "\\1" => "\\1" Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/