2007/9/10, Ronald Fischer <ronald.fischer / venyon.com>:
> > > data=%q(')
> > > puts ":"+data+" replace quotes by "+%q(\\')
> > >         data.gsub!(/'/,%q(\\'))
> > > puts "data length now #{data.length}"
> > >
> > > This produced as output:
> > >
> > > :' replace quotes by \'
> > > data length now 0
> > >
> > > From this I conclude that the gsub! had shortened the
> > string to length
> > > zero.
> > > Any explanation for this? How do I solve my problem in a proper way?
> >
> > This comes up frequently.
>
> I'm sorry if I posted a question which has been answered already :-(
>
> > You need to be aware that there are several
> > levels of interpretation involved and so you need multiple levels of
> > escaping.  This is sometimes obscured by the fact that '\1' works
> > although it should read '\\1'.  These levels are: 1. string escaping,
> > 2. regexp replacement string escaping.
>
> Hmmm... I would understand your argument if I had a digit following
> a backslash (which would mean a backreference to the n-th group in
> the pattern), but here we have \', and this is not a back reference,
> isn't it? At least the discussion of String#gsub at
> http://www.ruby-doc.org/core/
> mentions only \1,\2,... etc. as back references.

No.  You want the backslash to be interpreted literally by the regexp
engine, i.e. you want to prevent the regexp engine from identifying
the backslash as a meta character.  This is independent from the
character *after* the backslash.

First, you need to escape every backslash in a string so it is
inserted literally (makes 2 backslashes). Then you need to escape a
backslash because otherwise the regexp engine will interpret it (makes
2*2=4 backslashes). Finally you need an additional backslash to ensure
the single quote is inserted into the string.

Btw, not only digits are meaningful in replacement patterns, but
single quote is as well (I believe it's the postmatch):

irb(main):012:0> puts "abc".gsub(/b/, '\\\'')
acc
=> nil
irb(main):013:0> puts "abc".gsub(/b/, '\\`')
aac
=> nil

Cheers

robert