Forum: Ruby gsub("\\", "\\\\") seems unintuitive

7a5a608eba96bc54912f3cf3a07e2e3b?d=identicon&s=25 John Woods (Guest)
on 2008-02-22 18:28
(Received via mailing list)
The following confusing behavior is noted in the pickaxe book (2nd ed)
on page 75:

   # I would expect two backslashes in the result
   irb> puts "\\".gsub("\\","\\\\")
   \

   # I would expect four backslashes in the result
   irb> puts "\\".gsub("\\","\\\\\\\\")
   \\

I can certainly work around it, but it seems unintuitive. Is there a
reason why gsub behaves this way? Just curious...
76e6530ed28dc38e4edf93be22e6ccf9?d=identicon&s=25 J. Cooper (nefigah)
on 2008-02-22 18:37
John Woods wrote:
> The following confusing behavior is noted in the pickaxe book (2nd ed)
> on page 75:
>
>    # I would expect two backslashes in the result
>    irb> puts "\\".gsub("\\","\\\\")
>    \
>
>    # I would expect four backslashes in the result
>    irb> puts "\\".gsub("\\","\\\\\\\\")
>    \\
>
> I can certainly work around it, but it seems unintuitive. Is there a
> reason why gsub behaves this way? Just curious...

It's not a gsub thing, per se--it's a string thing. Backslashes are used
in strings to escape special characters. One such character is a " mark.
If you want to write a " mark in the middle of a string, you have to
escape it with a backslash:
"They call me \"Mellow Yellow\" etc."

If you didn't, then the " would signify the end of the string!
Similarly, in the example you listed, if you just did:
"\"
then you end up with a string that ISN'T ended! Because you escaped the
next ". So, if you want a literal backslash, you have to escape the
backslash too: "\\"

It just looks confusing because you are escaping the escape character :)
2ee1a7960cc761a6e92efb5000c0f2c9?d=identicon&s=25 William James (Guest)
on 2008-02-22 18:41
(Received via mailing list)
On Feb 22, 11:27 am, John Woods <jqwo...@gmail.com> wrote:
>
> I can certainly work around it, but it seems unintuitive. Is there a
> reason why gsub behaves this way? Just curious...

puts "\\".gsub("\\"){"\\\\"}
Ef3aa7f7e577ea8cd620462724ddf73b?d=identicon&s=25 Rob Biedenharn (Guest)
on 2008-02-22 18:49
(Received via mailing list)
On Feb 22, 2008, at 12:27 PM, John Woods wrote:
>
> I can certainly work around it, but it seems unintuitive. Is there a
> reason why gsub behaves this way? Just curious...


Notwithstanding the earlier responses...

Since the replacement string is evaluated 'twice', once as a ruby
string literal and then again by gsub to look for group refrences like
'\1', you need to provide two levels of escaping for a backslash.

\ is "\\"
so two of them is "\\\\"
and you want gsub to see that so it need to have them escaped:  "\\\\\\
\\"

Whew!  Yeah, it's unfortunate, but backslash is doing double-duty
here: introducing a group reference to the regular expression and
escaping characters in a string literal (just like "\n", but also
itself).

-Rob

Rob Biedenharn    http://agileconsultingllc.com
Rob@AgileConsultingLLC.com
9dec3df8319c613f6f4f14a27da0fdb4?d=identicon&s=25 Kyle Schmitt (Guest)
on 2008-02-22 18:54
(Received via mailing list)
Just as a side note, this is typical in all real programming languages.
C, C++, Java, Perl, sh, etc.
I _believe_ it's also true in python, lithp/scheme, & (o)caml, but for
those I've either not used them, or not used them in so long I'm
unsure.

Some languages, like vb{6|script|.net}, use a doubled quote, but those
aren't really proper programing languages ;)

--Kyle
7a5a608eba96bc54912f3cf3a07e2e3b?d=identicon&s=25 John Woods (Guest)
on 2008-02-22 19:01
(Received via mailing list)
Thanks Rob, that's exactly what I was missing -- the second round of
escaping is necessary to make escaped references to regex groups work.
2119f016588ba13373484491bd2dd6d1?d=identicon&s=25 Joe Peck (fatcatt316)
on 2008-12-17 22:15
I stumbled onto this thread trying to figure out a similar problem...
2119f016588ba13373484491bd2dd6d1?d=identicon&s=25 Joe Peck (fatcatt316)
on 2008-12-17 22:19
Joe Peck wrote:
> I stumbled onto this thread trying to figure out a similar problem...

Dangit, I didn't mean to post the above message :)

Okay, I need to read a site name (like "joe.com") and put a \ in front
of the period (so it would be "joe\.com").  I'm having trouble with
this, I can't seem to get only ONE \ in front of the period...

>> "joe.com".gsub(/\./, "\\\.")
=> "joe\\.com"
>> "joe.com".gsub(/\./, "\\\\.")
=> "joe\\.com"

Anyone have a clue what to do?  I'm probably missing something simple.
9d4960f8319664f0f7896230eebace73?d=identicon&s=25 Glen Holcomb (Guest)
on 2008-12-17 22:29
(Received via mailing list)
On Wed, Dec 17, 2008 at 2:12 PM, Joe Peck <joe@notsleepy.com> wrote:

> => "joe\\.com"
> >> "joe.com".gsub(/\./, "\\\\.")
> => "joe\\.com"
>
> Anyone have a clue what to do?  I'm probably missing something simple.
> --
> Posted via http://www.ruby-forum.com/.
>
>
That's because you are in irb.  You are getting what you want try this:

puts "joe.com".gsub(/\./, "\\\\.")

Actually it might be more readable as gsub('.', '\.')

--
"Hey brother Christian with your high and mighty errand, Your actions
speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)
289cf19aa581c445915c072bf45c5e25?d=identicon&s=25 Todd Benson (Guest)
on 2008-12-18 00:06
(Received via mailing list)
On Wed, Dec 17, 2008 at 3:12 PM, Joe Peck <joe@notsleepy.com> wrote:
> => "joe\\.com"
>>> "joe.com".gsub(/\./, "\\\\.")
> => "joe\\.com"
>
> Anyone have a clue what to do?  I'm probably missing something simple.

You are looking at a string with escaping characters (i.e. what it
would look like in double quotes).  You can verify this by using #puts
or "joe.com".gsub('.', '\.').length.

hth,
Todd
2119f016588ba13373484491bd2dd6d1?d=identicon&s=25 Joe Peck (fatcatt316)
on 2008-12-18 16:20
Okay, those last two explanations helped clear up my confusion.  Thanks.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.