title: Ruby gsub group parameters do not work when preceded by escaped slashes
body: <p>I am trying to perform a trivial substitution, that in any other language I have come across, work as per the documentation.  However, my substitution fails for some reason.  The documentation examples list:</p>
  
  <pre><code>"hello".gsub(/[aeiou]/, '*')                  #=&gt; "h*ll*"
  "hello".gsub(/([aeiou])/, '&lt;\1&gt;')             #=&gt; "h&lt;e&gt;ll&lt;o&gt;"
  "hello".gsub(/./) {|s| s.ord.to_s + ' '}      #=&gt; "104 101 108 108 111 "
  "hello".gsub(/(?&lt;foo&gt;[aeiou])/, '{\k&lt;foo&gt;}')  #=&gt; "h{e}ll{o}"
  'hello'.gsub(/[eo]/, 'e' =&gt; 3, 'o' =&gt; '*')    #=&gt; "h3ll*"
  </code></pre>
  
  <p>I am using the second form, to match <code>[</code> and <code>]</code> characters in a string and escape them  The regular expression is working correctly, but the substitution is not:</p>
  
  <pre><code>print "example[1][2].dat".gsub(/(\[|\])/, "[\\\1]")
  </code></pre>
  
  <p>The resultant output is:</p>
  
  <pre><code>$ ruby -e 'print "example[1][2].dat\n".gsub(/(\[|\])/, "[\\\1]")'
  example[\]1[\][\]2[\].dat
  </code></pre>
  
  <p>The correct output should be as demonstrated by Python:</p>
  
  <pre><code>$ python -c 'import re ; print re.sub(r"(\[|\])", r"[\\\1]", "example[1][2].dat")'
  example[\[]1[\]][\[]2[\]].dat
  </code></pre>
  
  <p>And even Perl handles it with grace:</p>
  
  <pre><code>$ perl -pe &lt;&lt;&lt;"example[1][2].dat" 's/(\[|\])/[\\\1]/g
  example[\[]1[\]][\[]2[\]].dat
  </code></pre>
  
  <p>I am guessing it is because the slashes are not being treated in raw form in the Ruby implementation, but in Python, that's easily solved by prefixing the strings with <code>r</code> - <code>r"[\\\1]"</code>.  Playing further, it seems Ruby doesn't cope well being passed strings on the command line, with double escaping everything, in order to be able to pass single quotes to Ruby's interpreter:</p>
  
  <pre><code>$ ruby -e 'print "example[1][2].dat\n".gsub(/(\[|\])/, '"'"'[\1]'"'"')'
  </code></pre>
  
  <p>To simplify, I placed all that in a small script instead:</p>
  
  <pre><code>#!/usr/bin/env ruby
  print "example[1][2].dat\n".gsub(/(\[|\])/, '[\1]')
  </code></pre>
  
  <p>Now the result at least yields the group parameter:</p>
  
  <pre><code>$ /tmp/re.rb
  example[[]1[]][[]2[]].dat
  </code></pre>
  
  <p>But with the slashes it fails:</p>
  
  <pre><code>#!/usr/bin/env ruby
  print "example[1][2].dat\n".gsub(/(\[|\])/, '[\\\1]')
  </code></pre>
  
  <p>And run it...</p>
  
  <pre><code>$ /tmp/re.rb
  example[\1]1[\1][\1]2[\1].dat
  </code></pre>
  
  <p>So I tried another solution from the documentation:</p>
  
  <pre><code>#!/usr/bin/env
  print "example[1][2].dat\n".gsub(/(\[|\])/, { ']' =&gt; '[\\]]', '[' =&gt; '[\\[]' })
  </code></pre>
  
  <p>Which actually seems to work:</p>
  
  <pre><code>$ /tmp/re.rb
  example[\[]1[\]][\[]2[\]].dat
  </code></pre>
  
  <p>Which is now identical to the python implementation:</p>
  
  <pre><code>$ python -c 'import re ; print re.sub(r"(\[|\])", r"[\\\1]", "example[1][2].dat")'
  example[\[]1[\]][\[]2[\]].dat
  </code></pre>
  
  <p><strong>Question</strong></p>
  
  <p>Is there an easier way to accomplish this without needing to elaborate on each character I already matched in the expression?</p>