Bug in gsub with "\\"?

In a program I worked on, I wanted to replace all single-quotes
with a backslash+single_quote. The following simple program:

  somestr = "'This isn't right.'"
  printf " Orig A: %s\n", somestr
  printf " Test A1: %s\n", somestr.gsub(/'/, "\\'")
  printf " Test A2: %s\n", somestr.gsub(/'/, "\\=")
  printf " Test A3: %s\n", somestr.gsub(/'/) { |s| "\\'"}
  printf "\n"
  somestr = "=This isn=t right.="
  printf " Orig B: %s\n", somestr
  printf " Test B1: %s\n", somestr.gsub(/=/, "\\'")
  printf " Test B2: %s\n", somestr.gsub(/=/, "\\=")
  printf " Test B3: %s\n", somestr.gsub(/=/) { |s| "\\="}
  exit 0

Prints out:

Orig A: 'This isn't right.'
Test A1: This isn't right.'This isnt right.'t right.
Test A2: \=This isn\=t right.\=
Test A3: \'This isn\'t right.\'

Orig B: =This isn=t right.=
Test B1: This isn=t right.=This isnt right.=t right.
Test B2: \=This isn\=t right.\=
Test B3: \=This isn\=t right.\=

The output from TestA1 and TestB1 seem a bit odd to me...
I am running: ruby 1.8.2 (2004-07-29) [i386-freebsd5]

···

--
Garance Alistair Drosehn = drosihn@gmail.com
Senior Systems Programmer or gad@FreeBSD.org
Rensselaer Polytechnic Institute; Troy, NY; USA

This is working as designed. Not clean, but it's right.

  irb(main):003:0> puts somestr.gsub(/'/, "\\\\'") # => \'This isn\'t right.\'

You need \\ for each \ you want in the actual string; your version
goes from \\' to \', which is just '. Your second version (\\=)
represents a string that isn't a "valid" escape.

-austin

···

On Wed, 18 Aug 2004 04:47:16 +0900, Garance A Drosehn <drosihn@gmail.com> wrote:

In a program I worked on, I wanted to replace all single-quotes
with a backslash+single_quote. The following simple program:

  somestr = "'This isn't right.'"
  printf " Orig A: %s\n", somestr
  printf " Test A1: %s\n", somestr.gsub(/'/, "\\'")
  printf " Test A2: %s\n", somestr.gsub(/'/, "\\=")
  printf " Test A3: %s\n", somestr.gsub(/'/) { |s| "\\'"}
  printf "\n"
  somestr = "=This isn=t right.="
  printf " Orig B: %s\n", somestr
  printf " Test B1: %s\n", somestr.gsub(/=/, "\\'")
  printf " Test B2: %s\n", somestr.gsub(/=/, "\\=")
  printf " Test B3: %s\n", somestr.gsub(/=/) { |s| "\\="}
  exit 0

Prints out:

Orig A: 'This isn't right.'
Test A1: This isn't right.'This isnt right.'t right.
Test A2: \=This isn\=t right.\=
Test A3: \'This isn\'t right.\'

Orig B: =This isn=t right.=
Test B1: This isn=t right.=This isnt right.=t right.
Test B2: \=This isn\=t right.\=
Test B3: \=This isn\=t right.\=

The output from TestA1 and TestB1 seem a bit odd to me...
I am running: ruby 1.8.2 (2004-07-29) [i386-freebsd5]

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Garance A Drosehn wrote:

In a program I worked on, I wanted to replace all single-quotes
with a backslash+single_quote. The following simple program:

somestr = "'This isn't right.'"
printf " Orig A: %s\n", somestr
printf " Test A1: %s\n", somestr.gsub(/'/, "\\'")
printf " Test A2: %s\n", somestr.gsub(/'/, "\\=")
printf " Test A3: %s\n", somestr.gsub(/'/) { |s| "\\'"}
printf "\n"
somestr = "=This isn=t right.="
printf " Orig B: %s\n", somestr
printf " Test B1: %s\n", somestr.gsub(/=/, "\\'")
printf " Test B2: %s\n", somestr.gsub(/=/, "\\=")
printf " Test B3: %s\n", somestr.gsub(/=/) { |s| "\\="}
exit 0

Prints out:

Orig A: 'This isn't right.'
Test A1: This isn't right.'This isnt right.'t right.
Test A2: \=This isn\=t right.\=
Test A3: \'This isn\'t right.\'

Orig B: =This isn=t right.=
Test B1: This isn=t right.=This isnt right.=t right.
Test B2: \=This isn\=t right.\=
Test B3: \=This isn\=t right.\=

The output from TestA1 and TestB1 seem a bit odd to me...
I am running: ruby 1.8.2 (2004-07-29) [i386-freebsd5]

when Ruby parses the string "\\'" it converts it into "\'" which is passed into gsub. within gsub \' is a reference to the part of the string to the right of the part that matched, which is why you get the results you're seeing.

A way that would work is

somestr.gsub(/'/, "\\\\'")

or to stick to using the block form

···

--
Mark Sparshatt

Ah. Okay -- thanks for the explanation!

···

On Wed, 18 Aug 2004 05:02:41 +0900, mark sparshatt <msparshatt@yahoo.co.uk> wrote:

when Ruby parses the string "\\'" it converts it into "\'" which is
passed into gsub. within gsub \' is a reference to the part of the
string to the right of the part that matched, which is why you get the
results you're seeing.

A way that would work is

somestr.gsub(/'/, "\\\\'")

or to stick to using the block form

--
Garance Alistair Drosehn = drosihn@gmail.com
Senior Systems Programmer
Rensselaer Polytechnic Institute; Troy, NY; USA