0

I am looking for a version of gsub which doesn't try to interpret its input as regular expressions and uses normal C-like escaped strings.

Update

The question was initiated by a strange behavior:

text.gsub("pattern", "\\\\\\")

and

text.gsub("pattern", "\\\\\\\\")

are treated as the same, and

text.gsub("pattern", "\\\\")

is treated as single backslash.

Paul
  • 25,812
  • 38
  • 124
  • 247

2 Answers2

3

There are two layers of escaping for the second parameter of gsub:

The first layer is Ruby string constant. If it is written like \\\\\\ it is unescaped by Ruby like \\\

the second layer is gsub itself: \\\ is treated like \\ + \

double backslash is resolved into single: \\ => \ and the single trailing backslash at the end is resolved as itself.

8 backslashes are parsed in the similar way:

"\\\\\\\\" => "\\\\"

and then

"\\\\" => "\\"

so the constants consisting of six and eight backslashes are resolved into two backslashes.

To make life a bit easier, a block may be used in gsub function. String constants in a block are passed only through Ruby layer (thanks to @Sorrow).

"foo\\bar".gsub("\\") {"\\\\"}
Paul
  • 25,812
  • 38
  • 124
  • 247
2

gsub accepts strings as first parameter:

the pattern is typically a Regexp; if given as
a String, any regular expression metacharacters
it contains will be interpreted literally

Example:

"hello world, i am thy code".gsub("o", "-foo-")
=> "hell-foo- w-foo-rld, i am thy c-foo-de"
Miki
  • 7,052
  • 2
  • 29
  • 39
  • Then why to replace to two backslashes \\ I have to write SIX backslashes? "\\\\\\" See here: http://stackoverflow.com/questions/1542214/weird-backslash-substitution-in-ruby – Paul Mar 28 '13 at 12:34
  • not quite sure what you mean... `"foo\\\\bar".gsub("\\\\", "-")` results in `"foo-bar"` (also `"foo\\\\bar".count('\\') == 2`) as long as you operate on strings, that is... if you do it the other way around (replace something with two \s) - the answer is in the thread you linked (gruesome details ;); for that reason (and for other clarity reasons) I would recommend you to use block syntax of `gsub` instead of two parameters – Miki Mar 28 '13 at 13:39
  • Try to replace single backslash to double backslash and you'll see. – Paul Mar 28 '13 at 14:11
  • 2
    yup, it does not work when you use two arguments for gsub, but it works when you use a block call: `"foo\\bar".gsub("\\") {"\\\\"}` – Miki Mar 28 '13 at 14:44