26

I'm trying to replace backslashes in my string with two backslashes like so:

str.gsub!("\\", "\\\\")

But, it doesn't do anything. I'm confused...

Tony R
  • 11,224
  • 23
  • 76
  • 101

1 Answers1

23

Note that this answer was givin in the contect of ruby 1.9. As ruby 2.0 has a new regex engine it might not be valid in that context.

This works:

str.gsub!("\\", "\\\\\\") 
str.gsub!("\\", "\\\\\\\\") # also, will always work

Edit: Explanation (via http://www.ruby-forum.com/topic/143645 provided by @vache)

Disclaimer: I'm not familiar with the inner workings of ruby's regex engine, any info here is deducted from the article mentioned above.

The basic thing to know is that the replacement string gets evaluated 2 times.

The first time the slashes do their job as escapes in the string, in the second time gsub will search the string for group references.

as @chris-johnsen mentioned, 6 slashes do not alway work. This leads me to believe something like this is happening:

For 6 slashes. 3 slashes are passed to the group reference layer. The trailing slash is interpreted not as an escape character because nothing is coming after it, it is interpreted as a backslash. So finally this layer returns 2 slashes. If anything would be trailing it, the expression will fail, as the third slash will now function as an escape character.

For 8 slashes: 4 slashes are passed to the group reference layer. The four slashes will in turn be reduced to two.

Bert Goethals
  • 7,867
  • 2
  • 20
  • 32
  • 5
    There is a discussion [here](http://www.ruby-forum.com/topic/143645) about why it's like this. – dee-see Jun 02 '11 at 01:39
  • 1
    if you add explanation (Vache's link is helpful), I'll accept your answer. I don't like accepting answers that give the solution without explaining WHY it's the solution. Also can you explain why it works with both 6 and 8 backslashes, because I don't quite understand that myself... – Tony R Jun 02 '11 at 02:05
  • It would also be nice to mention why six only works if it is not (in the general case) followed by `&`, `'`, `\``, `1`–`9`, `+`, or `k` (ampersand, single quote, back quote, non-zero digit, plus, or a named capture). – Chris Johnsen Jun 02 '11 at 02:10