gsub and \\\\

B

Bill Kelly

Hi,

I'm probably being dense, but -
=> "ab\\cd"

I expected the above to produce "ab\\\\cd"

If i add a character in between the \\\\, then
I do get two backslashes in the result:
=> "ab\\a\\cd"

If I add a third backslash in the replacement string,
then I get two in the result:
=> "ab\\\\cd"


Is this the expected behavior? If so, what's the
principle I need to know to understand it? :)

(ruby 1.8.2 (2004-07-29) [i386-mswin32] and
ruby 1.8.2 (2004-11-06) [i686-linux])


Thanks,

Regards,

Bill
 
F

Florian Gross

Bill said:
I'm probably being dense, but -

Here's the details, this comes up frequently:

..gsub adds its own layer of escaping. \1 refers to the first match, \2
to the second and there is also stuff like \'. (In general those forms
are equivalent to global variables. E.g. \1 => $1)

Because Ruby's String literals already have one level of escaping you
have to escape everything two times which is confusing.

You can do the above like this:

"ab\\cd".gsub(/\\/) { "\\\\" } # replaces one slash with two
"ab\\cd".gsub(/\\/, "\\\\\\\\" } # same

Of course having that meta layer available can make sense when you don't
want to use a block:

"foobar quxquv".gsub(/\w(\w+)/, "\\1") # or in most cases also
"foobar quxquv".gsub(/\w(\w+)/, '\1') # but note that
"foobar quxquv".gsub(/\w(\w+)/, '\\\\') # replace with one slash

Personally I'd like this mess to be fixed by using $ instead of \ for
the escaping layer of .gsub. That would yield code like this:

"foobar quxquv".gsub(/\w(\w+)/, "$1")
"ab\\cd".gsub(/\\/, "\\\\")
"Give me $1".gsub("$1", "$$2") # dollar needs to be escaped, new case

I don't know if matz also thinks that the latter version would be better
than the current one, but even if it is like that there's still the
problem of compatibility...
 
B

Bill Kelly

From: "Florian Gross said:
Here's the details, this comes up frequently:

..gsub adds its own layer of escaping. \1 refers to the first match, \2
to the second and there is also stuff like \'. (In general those forms
are equivalent to global variables. E.g. \1 => $1)

Because Ruby's String literals already have one level of escaping you
have to escape everything two times which is confusing.

Argh! Thanks....!! I used to know this... :)


Regards,

Bill
 
R

Robert Klemme

Florian Gross said:
Here's the details, this comes up frequently:

In fact we could make this thread sticky - if that were possible with news
and mail readers. :)

Just to add one point to your excellent explanation: Another source of
confusion in this context is irb which uses String#inspect which in turn
adds escaping again:

irb(main):001:0> s = "a\\b"
=> "a\\b"
irb(main):002:0> puts s
a\b
=> nil

Kind regards

robert
 
S

Sea&Gull

Because Ruby's String literals already have one level of escaping you
have to escape everything two times which is confusing.

Could you please give some more details? I still do not understand
how gsub works...

irb(main):101:0* puts "aa\\bb".gsub(/\\/, "\\")
aa\bb
=> nil
irb(main):102:0> puts "aa\\bb".gsub(/\\/, "\\\\")
aa\bb
=> nil
irb(main):103:0> puts "aa\\bb".gsub(/\\/, "\\\\\\")
aa\\bb
=> nil
irb(main):104:0> puts "aa\\bb".gsub(/\\/, "\\\\\\\\")
aa\\bb
=> nil
irb(main):105:0> puts "aa\\bb".gsub(/\\/, "\\\\\\\\\\")
aa\\\bb
=> nil
irb(main):106:0> puts "aa\\bb".gsub(/\\/, "\\\\\\\\\\\\")
aa\\\bb
=> nil
irb(main):107:0> puts "aa\\bb".gsub(/\\/, "\\\\\\\\\\\\\\")
aa\\\\bb
=> nil
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top