# Finding "\\" in a string

**URL:** <https://rubytalk.org/t/finding-in-a-string/29407>\
**Category:** ruby-talk\
**Created:** [28 July 2006 20:11 UTC](https://rubytalk.org/t/finding-in-a-string/29407 "2006-07-28T20:11:00Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [28 July 2006 20:11 UTC](https://rubytalk.org/t/finding-in-a-string/29407/1 "2006-07-28T20:11:00Z")

</div>

I'm going crazy, right? Surely it is possible  
to find a backslash (\) in a string, and  
replace it with two backslashes. That's simple,  
right? Just gsub("\\", '\\'). That's all there  
is to it.

Except that...

#!/usr/bin/env ruby

testpath = "\\foo\\bar"  
p testpath # =\> "\\foo\\bar" --representation  
puts testpath # =\> \foo\bar --what you see

result = testpath.gsub("\\", '\\')  
p result # =\> "\\foo\\bar"  
&nbsp;&nbsp;&nbsp;(represenation unchanged. Should be "\\\\foo\\\\bar")

puts result # =\> \foo\bar  
&nbsp;&nbsp;&nbsp;(unchanged. should be \\foo\\bar)

I've tried lots of gsub variations, like  
&nbsp;&nbsp;&nbsp;&nbsp;/\\/, '\\', "\\\\", and anything else I could  
think of that came even close to being sensible,  
but I've yet to find anything that works.

My workaround will be to add a sed script to  
filter the input. But surely that isn't necessary.  
Is it?

---

<div class="post-metadata">

**Author:** ![Arnaud\_Bergeron](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@Arnaud\_Bergeron](https://rubytalk.org/u/Arnaud_Bergeron)\
**Post date:** [28 July 2006 20:21 UTC](https://rubytalk.org/t/finding-in-a-string/29407/2 "2006-07-28T20:21:09Z")

</div>

> I'm going crazy, right? Surely it is possible  
> to find a backslash (\) in a string, and  
> replace it with two backslashes. That's simple,  
> right? Just gsub("\\", '\\'). That's all there  
> is to it.

> puts '\\'

\  
=\> nil

You are replacing single slashes with sigle slashes.

> **···**
>
> On 7/28/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> 
> > Except that...
> > 
> > #!/usr/bin/env ruby
> > 
> > testpath = "\\foo\\bar"  
> > p testpath # =\> "\\foo\\bar" --representation  
> > puts testpath # =\> \foo\bar --what you see
> > 
> > result = testpath.gsub("\\", '\\')  
> > p result # =\> "\\foo\\bar"  
> > &nbsp;&nbsp;&nbsp;(represenation unchanged. Should be "\\\\foo\\\\bar")
> > 
> > puts result # =\> \foo\bar  
> > &nbsp;&nbsp;&nbsp;(unchanged. should be \\foo\\bar)
> > 
> > I've tried lots of gsub variations, like  
> > &nbsp;&nbsp;&nbsp;&nbsp;/\\/, '\\', "\\\\", and anything else I could  
> > think of that came even close to being sensible,  
> > but I've yet to find anything that works.
> > 
> > My workaround will be to add a sed script to  
> > filter the input. But surely that isn't necessary.  
> > Is it?
> 
> --  
> "i think we should rewrite the kernel in java since it has good  
> support for threads." - Ted Unangst

---

<div class="post-metadata">

**Author:** ![Paul\_Battley](https://avatars.discourse-cdn.com/v4/letter/p/f07891/32.png) [@Paul\_Battley](https://rubytalk.org/u/Paul_Battley)\
**Post date:** [28 July 2006 21:52 UTC](https://rubytalk.org/t/finding-in-a-string/29407/3 "2006-07-28T21:52:55Z")

</div>

You're not going crazy. You just need eight of 'em. Yes, really!

testpath = "\\foo\\bar"  
result = testpath.gsub("\\", "\\\\\\\\")  
p result # =\> "\\\\foo\\\\bar"

Paul.

> **···**
>
> On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> 
> > I'm going crazy, right? Surely it is possible  
> > to find a backslash (\) in a string, and  
> > replace it with two backslashes. That's simple,  
> > right? Just gsub("\\", '\\'). That's all there  
> > is to it.

---

<div class="post-metadata">

**Author:** ![W\_James](https://avatars.discourse-cdn.com/v4/letter/w/e274bd/32.png) [@W\_James](https://rubytalk.org/u/W_James)\
**Post date:** [29 July 2006 00:00 UTC](https://rubytalk.org/t/finding-in-a-string/29407/4 "2006-07-29T00:00:09Z")

</div>

Eric Armstrong wrote:

> I'm going crazy, right? Surely it is possible  
> to find a backslash (\) in a string, and  
> replace it with two backslashes. That's simple,  
> right? Just gsub("\\", '\\'). That's all there  
> is to it.
> 
> Except that...
> 
> #!/usr/bin/env ruby
> 
> testpath = "\\foo\\bar"  
> p testpath # =\> "\\foo\\bar" --representation  
> puts testpath # =\> \foo\bar --what you see
> 
> result = testpath.gsub("\\", '\\')  
> p result # =\> "\\foo\\bar"  
> &nbsp;&nbsp;&nbsp;(represenation unchanged. Should be "\\\\foo\\\\bar")
> 
> puts result # =\> \foo\bar  
> &nbsp;&nbsp;&nbsp;(unchanged. should be \\foo\\bar)
> 
> I've tried lots of gsub variations, like  
> &nbsp;&nbsp;&nbsp;&nbsp;/\\/, '\\', "\\\\", and anything else I could  
> think of that came even close to being sensible,  
> but I've yet to find anything that works.
> 
> My workaround will be to add a sed script to  
> filter the input. But surely that isn't necessary.  
> Is it?

> > puts "\\foo\\bar".gsub(/\\/, '\&\&' )

\\foo\\bar

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [28 July 2006 21:50 UTC](https://rubytalk.org/t/finding-in-a-string/29407/5 "2006-07-28T21:50:24Z")

</div>

Arnaud Bergeron wrote:

> > I'm going crazy, right? Surely it is possible  
> > to find a backslash (\) in a string, and  
> > replace it with two backslashes. That's simple,  
> > right? Just gsub("\\", '\\'). That's all there  
> > is to it.
> 
> \> puts '\\'  
> \  
> =\> nil
> 
> You are replacing single slashes with single slashes.

You would think so, wouldn't you? But note that  
I've used single quotes for the replacement.  
So it /should/ equate to two backslashes.

So I tried four of them in the replacement string.  
I did so yesterday, in fact, and repeated the  
experiment today:

&nbsp;&nbsp;&nbsp;testpath = "\\foo\\bar"  
&nbsp;&nbsp;&nbsp;result = testpath.gsub("\\", '\\\\')  
&nbsp;&nbsp;&nbsp;p result # =\> "\\foo\\bar" (s/b "\\\\foo\\\\bar"  
&nbsp;&nbsp;&nbsp;puts result # =\> \foo\bar (s/b \\foo\\bar)

Notice that the results are unchanged. So I tried a  
simple character: testpath.gsub("\\", 'r')

That worked as expected:

&nbsp;&nbsp;&nbsp;"\\foo\\bar"  
&nbsp;&nbsp;&nbsp;\foo\bar  
&nbsp;&nbsp;&nbsp;"rfoorbar"  
&nbsp;&nbsp;&nbsp;rfoorbar

So it would appear that something strange is happening  
in the evaluation of the gsub replacement string.

> **···**
>
> > On 7/28/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> 
> > > Except that...
> > > 
> > > #!/usr/bin/env ruby
> > > 
> > > testpath = "\\foo\\bar"  
> > > p testpath # =\> "\\foo\\bar" --representation  
> > > puts testpath # =\> \foo\bar --what you see
> > > 
> > > result = testpath.gsub("\\", '\\')  
> > > p result # =\> "\\foo\\bar"  
> > > &nbsp;&nbsp;&nbsp;(represenation unchanged. Should be "\\\\foo\\\\bar")
> > > 
> > > puts result # =\> \foo\bar  
> > > &nbsp;&nbsp;&nbsp;(unchanged. should be \\foo\\bar)
> > > 
> > > I've tried lots of gsub variations, like  
> > > &nbsp;&nbsp;&nbsp;&nbsp;/\\/, '\\', "\\\\", and anything else I could  
> > > think of that came even close to being sensible,  
> > > but I've yet to find anything that works.
> > > 
> > > My workaround will be to add a sed script to  
> > > filter the input. But surely that isn't necessary.  
> > > Is it?

---

<div class="post-metadata">

**Author:** ![Paul\_Battley](https://avatars.discourse-cdn.com/v4/letter/p/f07891/32.png) [@Paul\_Battley](https://rubytalk.org/u/Paul_Battley)\
**Post date:** [29 July 2006 00:09 UTC](https://rubytalk.org/t/finding-in-a-string/29407/6 "2006-07-29T00:09:20Z")

</div>

Nice solution.

> **···**
>
> On 29/07/06, William James \<w\_a\_x\_man@yahoo.com\> wrote:
> 
> > \>\> puts "\\foo\\bar".gsub(/\\/, '\&\&' )  
> > \\foo\\bar

---

<div class="post-metadata">

**Author:** ![Paul\_Battley](https://avatars.discourse-cdn.com/v4/letter/p/f07891/32.png) [@Paul\_Battley](https://rubytalk.org/u/Paul_Battley)\
**Post date:** [28 July 2006 21:57 UTC](https://rubytalk.org/t/finding-in-a-string/29407/7 "2006-07-28T21:57:54Z")

</div>

That's right. The replacement string understands back-references of  
the form \1, \2 etc, so there's another level of escaping needed.

"\\" \<- one backslash  
"\\\\" \<- two backslashes  
"\\\\\\\\" \<- four backslashes, or two backslashes in replacement string

Paul.

> **···**
>
> On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> 
> > So it would appear that something strange is happening  
> > in the evaluation of the gsub replacement string.

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [29 July 2006 00:28 UTC](https://rubytalk.org/t/finding-in-a-string/29407/8 "2006-07-29T00:28:09Z")

</div>

Paul Battley wrote:

> **···**
>
> > On 29/07/06, William James \<w\_a\_x\_man@yahoo.com\> wrote:
> > 
> > > \>\> puts "\\foo\\bar".gsub(/\\/, '\&\&' )  
> > > \\foo\\bar
> > 
> > Nice solution.
> 
> I'll say! Wild! What makes /that/ work???

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [28 July 2006 22:49 UTC](https://rubytalk.org/t/finding-in-a-string/29407/9 "2006-07-28T22:49:49Z")

</div>

Paul Battley wrote:

> > So it would appear that something strange is happening  
> > in the evaluation of the gsub replacement string.
> 
> That's right. The replacement string understands back-references of  
> the form \1, \2 etc, so there's another level of escaping needed.
> 
> "\\" \<- one backslash  
> "\\\\" \<- two backslashes  
> "\\\\\\\\" \<- four backslashes, or two backslashes in replacement string

Very helpful. At least now I have a good idea that it  
can be made to work. Now let's see if I can dial in my understanding with respect to replacement strings...

The fact that \1, \2 are recognized /shouldn't/ matter,  
because the tokenizer really ought to ignore any \x  
sequence where the x isn't a known special character.  
But it's rapidly becoming apparent that the tokenizer  
takes any \x and translates it to /something/, so we  
need \\ to get one \ in the string.

Now then, we need two backslashes, so four of them  
/should/ have worked inside single quotes. (And if  
if takes 4 to make 1, why wasn't I effectively  
removing the existing quotes when I only supplied two.)

I've seen a similar situation in Java, where it took  
2 slashes to get one past the language parser, and  
it also took two to get one past the regular expression  
parser, so in that case it took four slashes to get  
one into the regular expression. That's the most  
complex case I've seen before this, but note that it  
was the \_regular expression\_ that needed four to get one.  
It wasn't the replacement string. The replacement string  
shouldn't be going through the reg exp parser, so it  
shouldn't require that many.

It seems that it does, though. Huh?

> **···**
>
> > On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:

---

<div class="post-metadata">

**Author:** ![W\_James](https://avatars.discourse-cdn.com/v4/letter/w/e274bd/32.png) [@W\_James](https://rubytalk.org/u/W_James)\
**Post date:** [29 July 2006 00:50 UTC](https://rubytalk.org/t/finding-in-a-string/29407/10 "2006-07-29T00:50:12Z")

</div>

Eric Armstrong wrote:

> Paul Battley wrote:  
> \>\> \>\> puts "\\foo\\bar".gsub(/\\/, '\&\&' )  
> \>\> \\foo\\bar  
> \>  
> \> Nice solution.  
> \>  
> I'll say! Wild! What makes /that/ work???

\& is simply what was matched by the regex.

It's similar in awk:

BEGIN {  
&nbsp;&nbsp;s = " foo "  
&nbsp;&nbsp;sub(/[^]+/, "&&&", s)  
&nbsp;&nbsp;print s  
}

&nbsp;&nbsp;&nbsp;===\> foofoofoo

> **···**
>
> > \> On 29/07/06, William James \<w\_a\_x\_man@yahoo.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Paul\_Battley](https://avatars.discourse-cdn.com/v4/letter/p/f07891/32.png) [@Paul\_Battley](https://rubytalk.org/u/Paul_Battley)\
**Post date:** [28 July 2006 23:10 UTC](https://rubytalk.org/t/finding-in-a-string/29407/11 "2006-07-28T23:10:09Z")

</div>

In fact, the tokenizer \*does\* ignore non-special sequences:

"\\foo".gsub("\\", "\\x") # =\> "\\xfoo"

And if there's nothing else left in the string, that works, too:

"\\foo".gsub("\\", "\\") # =\> "\\foo"

However, in order to be able to produce a literal \1, it also needs to  
understand \\. Therefore, this gives the same effect:

"\\foo".gsub("\\", "\\\\") # =\> "\\foo"

But I missed a trick earler. We only actually need six backslashes to  
emit two: the end of the string will terminate the sequence as in the  
second example:

"\\foo".gsub("\\", "\\\\\\") # =\> "\\\\foo"

Is it getting clearer?

Paul.

> **···**
>
> On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> 
> > Very helpful. At least now I have a good idea that it  
> > can be made to work. Now let's see if I can dial in my  
> > understanding with respect to replacement strings...
> > 
> > The fact that \1, \2 are recognized /shouldn't/ matter,  
> > because the tokenizer really ought to ignore any \x  
> > sequence where the x isn't a known special character.  
> > But it's rapidly becoming apparent that the tokenizer  
> > takes any \x and translates it to /something/, so we  
> > need \\ to get one \ in the string.

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [29 July 2006 19:55 UTC](https://rubytalk.org/t/finding-in-a-string/29407/12 "2006-07-29T19:55:22Z")

</div>

William James wrote:

> Eric Armstrong wrote:
> 
> > Paul Battley wrote:
> > 
> > > > > > puts "\\foo\\bar".gsub(/\\/, '\&\&' )
> > > > 
> > > > \\foo\\bar
> > > 
> > > Nice solution.
> > 
> > I'll say! Wild! What makes /that/ work???
> 
> \& is simply what was matched by the regex.

Too cool. I love it.  
Thanks.

Another instructive thread.  
What a great list.  
:\_)

> **···**
>
> > > > On 29/07/06, William James \<w\_a\_x\_man@yahoo.com\> wrote:

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [28 July 2006 23:18 UTC](https://rubytalk.org/t/finding-in-a-string/29407/13 "2006-07-28T23:18:18Z")

</div>

This is why when I need to gsub backslashes I use a block:

gsub(%r{\}) { '\\' }

> **···**
>
> On Jul 28, 2006, at 7:10 PM, Paul Battley wrote:
> 
> > On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> > 
> > > Very helpful. At least now I have a good idea that it  
> > > can be made to work. Now let's see if I can dial in my  
> > > understanding with respect to replacement strings...
> > > 
> > > The fact that \1, \2 are recognized /shouldn't/ matter,  
> > > because the tokenizer really ought to ignore any \x  
> > > sequence where the x isn't a known special character.  
> > > But it's rapidly becoming apparent that the tokenizer  
> > > takes any \x and translates it to /something/, so we  
> > > need \\ to get one \ in the string.
> > 
> > In fact, the tokenizer \*does\* ignore non-special sequences:
> > 
> > "\\foo".gsub("\\", "\\x") # =\> "\\xfoo"
> > 
> > And if there's nothing else left in the string, that works, too:
> > 
> > "\\foo".gsub("\\", "\\") # =\> "\\foo"
> > 
> > However, in order to be able to produce a literal \1, it also needs to  
> > understand \\. Therefore, this gives the same effect:
> > 
> > "\\foo".gsub("\\", "\\\\") # =\> "\\foo"
> > 
> > But I missed a trick earler. We only actually need six backslashes to  
> > emit two: the end of the string will terminate the sequence as in the  
> > second example:
> > 
> > "\\foo".gsub("\\", "\\\\\\") # =\> "\\\\foo"
> > 
> > Is it getting clearer?
> > 
> > Paul.

---

<div class="post-metadata">

**Author:** ![Paul\_Battley](https://avatars.discourse-cdn.com/v4/letter/p/f07891/32.png) [@Paul\_Battley](https://rubytalk.org/u/Paul_Battley)\
**Post date:** [28 July 2006 23:25 UTC](https://rubytalk.org/t/finding-in-a-string/29407/14 "2006-07-28T23:25:57Z")

</div>

That's much easier, but significantly slower:

s = "\\foo" \* 1000000

t0 = Time.now  
s.gsub("\\", "\\\\\\")  
p(Time.now - t0) # 1.394492

t0 = Time.now  
s.gsub("\\"){ "\\\\" }  
p(Time.now - t0) # 2.863728

If you are dealing with very long strings, it's probably worth the  
effort of ciphering the backslashes.

Paul.

> **···**
>
> On 29/07/06, Logan Capaldo \<logancapaldo@gmail.com\> wrote:
> 
> > This is why when I need to gsub backslashes I use a block:
> > 
> > gsub(%r{\}) { '\\' }

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [28 July 2006 23:30 UTC](https://rubytalk.org/t/finding-in-a-string/29407/15 "2006-07-28T23:30:16Z")

</div>

Omigawd. I'm more confused than ever! But  
I have some great patterns to follow until  
the day of my enlightenment arrives!

Thanks guys. I look forward to the day this  
all makes sense...  
:\_)

Logan Capaldo wrote:

> **···**
>
> > On Jul 28, 2006, at 7:10 PM, Paul Battley wrote:
> > 
> > > On 28/07/06, Eric Armstrong \<Eric.Armstrong@sun.com\> wrote:
> > > 
> > > > Very helpful. At least now I have a good idea that it  
> > > > can be made to work. Now let's see if I can dial in my  
> > > > understanding with respect to replacement strings...
> > > > 
> > > > The fact that \1, \2 are recognized /shouldn't/ matter,  
> > > > because the tokenizer really ought to ignore any \x  
> > > > sequence where the x isn't a known special character.  
> > > > But it's rapidly becoming apparent that the tokenizer  
> > > > takes any \x and translates it to /something/, so we  
> > > > need \\ to get one \ in the string.
> > > 
> > > In fact, the tokenizer \*does\* ignore non-special sequences:
> > > 
> > > "\\foo".gsub("\\", "\\x") # =\> "\\xfoo"
> > > 
> > > And if there's nothing else left in the string, that works, too:
> > > 
> > > "\\foo".gsub("\\", "\\") # =\> "\\foo"
> > > 
> > > However, in order to be able to produce a literal \1, it also needs to  
> > > understand \\. Therefore, this gives the same effect:
> > > 
> > > "\\foo".gsub("\\", "\\\\") # =\> "\\foo"
> > > 
> > > But I missed a trick earler. We only actually need six backslashes to  
> > > emit two: the end of the string will terminate the sequence as in the  
> > > second example:
> > > 
> > > "\\foo".gsub("\\", "\\\\\\") # =\> "\\\\foo"
> > > 
> > > Is it getting clearer?
> > > 
> > > Paul.
> > 
> > This is why when I need to gsub backslashes I use a block:
> > 
> > gsub(%r{\}) { '\\' }

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [28 July 2006 23:51 UTC](https://rubytalk.org/t/finding-in-a-string/29407/16 "2006-07-28T23:51:57Z")

</div>

Logan Capaldo wrote:

> when I need to gsub backslashes I use a block:
> 
> gsub(%r{\}) { '\\' }

That's odd. I would have expected that to work,  
since the value of the block is the value of  
the string.

But %r{\} produces:  
&nbsp;&nbsp;&nbsp;"unterminated string meets end of file"

And { '\\' } inserts a single backslash.

Paul's version worked:  
&nbsp;&nbsp;&nbsp;gsub("\\"){ "\\\\" }

As did this:  
&nbsp;&nbsp;&nbsp;gsub(%r{\\}) { '\\\\' }

Thanks for all the choices! I'm picking the  
version with the simplest syntax I'm likely  
to recall:  
&nbsp;&nbsp;&nbsp;gsub("\\") { '\\\\' }

It may be slower, but it's readable.

Thanks again, guys. There is no way on earth  
I would found the solution. Heck, even now  
that I see it, I don't really understand it.  
(I'm hoping that Paul's in-depth explanation  
will make more sense after I've read it 5 or  
6 times.)  
:\_)

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [28 July 2006 23:50 UTC](https://rubytalk.org/t/finding-in-a-string/29407/17 "2006-07-28T23:50:57Z")

</div>

I'm sure it is. I'll learn how to decipher backslashes in gsub when I come across those strings \<g\>

> **···**
>
> On Jul 28, 2006, at 7:25 PM, Paul Battley wrote:
> 
> > On 29/07/06, Logan Capaldo \<logancapaldo@gmail.com\> wrote:
> > 
> > > This is why when I need to gsub backslashes I use a block:
> > > 
> > > gsub(%r{\}) { '\\' }
> > 
> > That's much easier, but significantly slower:
> > 
> > s = "\\foo" \* 1000000
> > 
> > t0 = Time.now  
> > s.gsub("\\", "\\\\\\")  
> > p(Time.now - t0) # 1.394492
> > 
> > t0 = Time.now  
> > s.gsub("\\"){ "\\\\" }  
> > p(Time.now - t0) # 2.863728
> > 
> > If you are dealing with very long strings, it's probably worth the  
> > effort of ciphering the backslashes.
> > 
> > Paul.

---

<div class="post-metadata">

**Author:** ![Logan\_Capaldo](https://avatars.discourse-cdn.com/v4/letter/l/7ea924/32.png) [@Logan\_Capaldo](https://rubytalk.org/u/Logan_Capaldo)\
**Post date:** [28 July 2006 23:56 UTC](https://rubytalk.org/t/finding-in-a-string/29407/18 "2006-07-28T23:56:49Z")

</div>

> Logan Capaldo wrote:
> 
> > when I need to gsub backslashes I use a block:  
> > gsub(%r{\}) { '\\' }
> 
> That's odd. I would have expected that to work,  
> since the value of the block is the value of  
> the string.
> 
> But %r{\} produces:  
> &nbsp;&nbsp;"unterminated string meets end of file"
> 
> And { '\\' } inserts a single backslash.
> 
> Paul's version worked:  
> &nbsp;&nbsp;gsub("\\"){ "\\\\" }
> 
> As did this:  
> &nbsp;&nbsp;gsub(%r{\\}) { '\\\\' }
> 
> Thanks for all the choices! I'm picking the  
> version with the simplest syntax I'm likely  
> to recall:  
> &nbsp;&nbsp;gsub("\\") { '\\\\' }
> 
> It may be slower, but it's readable.
> 
> Thanks again, guys. There is no way on earth  
> I would found the solution. Heck, even now  
> that I see it, I don't really understand it.  
> (I'm hoping that Paul's in-depth explanation  
> will make more sense after I've read it 5 or  
> 6 times.)  
> :\_)

Sorry, that wasn't meant to be a \_real\_ example. It was just the idea of throwing the block out there so you didn't have to deal with the very domain specific logic of gsub's second argument.

> **···**
>
> On Jul 28, 2006, at 7:51 PM, Eric Armstrong wrote:
> 
> >

---

<div class="post-metadata">

**Author:** ![Eric\_Armstrong](https://avatars.discourse-cdn.com/v4/letter/e/46a35a/32.png) [@Eric\_Armstrong](https://rubytalk.org/u/Eric_Armstrong)\
**Post date:** [29 July 2006 00:17 UTC](https://rubytalk.org/t/finding-in-a-string/29407/19 "2006-07-29T00:17:15Z")

</div>

Logan Capaldo wrote:

> Sorry, that wasn't meant to be a \_real\_ example. It was just the idea of throwing the block out there so you didn't have to deal with the very domain specific logic of gsub's second argument.

No problem. If I had sufficient understanding, I would  
simply have filled in the blanks. Going through the  
exercise gave me a few more data points, so I have a  
better handle on what works--although I'm still mystified  
as to why.

At any rate, I appreciate the block trick. It's something  
I'm beginning to make more use of.
