Robert Klemme
5/22/2006 8:37:00 AM
Shea Martin wrote:
> ts wrote:
>>>>>>> "S" == Shea Martin <shea08@eastlink.ca> writes:
>>
>> Write it like this
>>
>> S> puts str.gsub( 'PATTERN', de_dir )
>>
>> puts str.gsub( 'PATTERN' ) { de_dir }
I recommend to rather double the number of backslashes in de_dir or use
Regexp.escape() because the block form is for dynamic replacements; it's
also slower for static replacements.
>> de_dir = "c:\\\\some\\\\dir"
=> "c:\\\\some\\\\dir"
>> str = "c:\\some\\path, PATTERN"
=> "c:\\some\\path, PATTERN"
>> puts str.gsub( 'PATTERN', de_dir )
c:\some\path, c:\some\dir
=> nil
>> puts str.gsub( 'PATTERN', Regexp.escape( de_dir ) )
c:\some\path, c:\\some\\dir
>> de_dir.gsub! /\\/, '\\\\\\\\'
=> "c:\\\\\\\\some\\\\\\\\dir"
>> puts str.gsub( 'PATTERN', de_dir )
c:\some\path, c:\\some\\dir
=> nil
> Thanks. I thought I had tried, that, but I guess not.
> BTW, is that a bug or designed behavior?
It's not a bug. People frequently stumble on this. There are simply
several layers of escaping: first there is the escaping for strings,
i.e. you need to escape a backslash in order to get it into a single
quoted or double quoted string. Then the RX engine uses backslash as
escape as well in substitution patterns. The reason why so many people
stumble here is that you can actually have \1 in a string which does not
result in 1 but in \1 which is a bit inconsistent (because \\ results in
\) but convenient for the usual case:
>> puts '\\'
=> nil
>> puts '\1'
\1
=> nil
So you can do
>> "foo".gsub /(.)/, '<\1>'
=> "<f><o><o>"
while you should IMHO be doing
>> "foo".gsub /(.)/, '<\\1>'
=> "<f><o><o>"
Cheers
robert