views:

94

answers:

3

I can't for the life of me figure this out, even though it should be very simple.

How can I replace all occurrences of "(" and ")" on a string with "\(" and "\)"?

Nothing seems to work:

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

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

Any idea?

A: 

In a string created with double quotes, \ escapes the next character. So in order to get a backslash in the string, you need to escape the backslash itself: "\\(". Or you could just use a single-quoted string, which does less preprocessing: '\('.

Chuck
+1  A: 

"foo ( bar ) foo".gsub("(", "\\\\(") does work. If you're trying it in console, you're probably seeing the \\( string because console outputs the string with inspect, that escapes the \

Try with: puts "foo ( bar ) foo".gsub("(", "\\(") and you'll see

Chubas
+1  A: 

You already have the solution with your second attempt, you were just confused because the string is displayed in escaped form in the interactive interpreter. But really there is only one backslash there not two. Try printing it using puts and you will see that there is in fact only one backslash:

> "foo ( bar ) foo".gsub("(", "\\(")
=> "foo \\( bar ) foo"
> puts "foo ( bar ) foo".gsub("(", "\\(")
foo \( bar ) foo

If you need further convincing, try taking the length of the string:

> "foo ( bar ) foo".length
=> 15
> "foo ( bar ) foo".gsub("(", "\\(").length
=> 16

If it had added two backslashes it would print 17 not 16.

Mark Byers
Thank you very much!
Todd Horrtyz