Escape Double and Single Backslashes in a String in Ruby

Escape double and single backslashes in a string in Ruby

Just double-up every backslash, like so:

"\\\\servername\\some windows share\\folder 1\\folder2\\"

Ruby replace double backslash with single backslash

With this line...

line = "this\\is\\a\\test"

... you actually create a string looking like this:

this\is\a\test

... as each \\ will be recognized as a single slash. Of course, you won't be able to replace double slashes, as there's none in your string.

line.gsub("\\", "_") line is doing just that: replacing all the single slashes in your string with _ symbol.

line.gsub("\\", "\\") is just a no-op in disguise.

Backslashes in single quoted strings vs. double quoted strings

I'd refer you to "Ruby Programming/Strings" for a very concise yet comprehensive overview of the differences.

From the reference:

puts "Betty's pie shop"

puts 'Betty\'s pie shop'

Because "Betty's" contains an apostrophe, which is the same character as the single quote, in the second line we need to use a backslash to escape the apostrophe so that Ruby understands that the apostrophe is in the string literal instead of marking the end of the string literal. The backslash followed by the single quote is called an escape sequence.

Ruby backslash escaping: ' \\ \hline' as string

You may have to escape all the backslashes:

str = "\\\\ \\hline"
puts str
# => \\ \hline

please notice that it also works if you use single quotes string and escape only the single backslashes:

str = '\\\\ \hline'
puts str
# => \\ \hline

and also if your backslash precedes something that may look like a char that can be escaped:

str = '\\\\ \nline'
puts str
# => \\ \nline

but this is not true if you use double quotes:

str = "\\\\ \nline"
puts str
# => \\
# => line

The escaping of all backslashes is not mandatory (as @mudasobwa correctly pointed out) and there are cases in which you may decide to not use it, but IMHO it is preferable, in particular if you use strings with double quotes.

How to keep single backslash in Ruby string after to_json formating?

My apologies, you do seem to have a valid issue on your hand. The key is this: Why is the slash an escapable character in JSON? and its duplicate target, JSON: why are forward slashes escaped?. Since both unescaped slashes and escaped slashes are allowed, Ruby chose to not escape them, and PHP chose to escape them, and both approaches are correct.

(Aside: there's a bit of a complication in talking about this because \ is an escape character both for a string literal, and for JSON strings. Thus, in this answer, I take care to puts (or echo/print_r) all the values, to see the strings that do not have the string literal backslash escapes, only the backslashes that are actually present in the strings.)

Thus, the JSON {"url":"http:\/\/example.com\/test"} is a representation of the Ruby hash { 'url' => 'http://example.com/test' }, where slashes are escaped (as PHP's json_encode would do it). Ruby's to_json' would render that as{"url":"http://example.com/test"}`:

# Ruby
json1 = '{"url":"http:\/\/example.com\/test"}'
puts json1 # => {"url":"http:\/\/example.com\/test"}
puts JSON.parse(json1) # => {"url"=>"http://example.com/test"}
puts JSON.parse(json1).to_json # => {"url":"http://example.com/test"}

# PHP
$json1 = '{"url":"http:\/\/example.com\/test"}';
echo $json1; # {"url":"http:\/\/example.com\/test"}
print_r(json_decode($json1)); # stdClass Object
# (
# [url] => http://example.com/test
# )
echo json_encode(json_decode($json1)); # {"url":"http:\/\/example.com\/test"}

On the other hand, {"url":"http:\\/\\/example.com\\/test"} (represented in Ruby and PHP as the string '{"url":"http:\\\\/\\\\/example.com\\\\/test"}') is a representation of the Ruby hash { 'url' => 'http:\/\/example.com\/test' }, where there are actual backslashes, but the slashes are not escaped. PHP's json_encode would render this value as {"url":"http:\\\/\\\/example.com\\\/test"}.

# Ruby
json2 = '{"url":"http:\\\\/\\\\/example.com\\\\/test"}'
puts json2 # => {"url":"http:\\/\\/example.com\\/test"}
puts JSON.parse(json2) # => {"url"=>"http:\\/\\/example.com\\/test"}
puts JSON.parse(json2).to_json # => {"url":"http:\\/\\/example.com\\/test"}

# PHP
$json2 = '{"url":"http:\\\\/\\\\/example.com\\\\/test"}';
echo $json2; # {"url":"http:\/\/example.com\/test"}
print_r(json_decode($json2)); # stdClass Object
# (
# [url] => http:\/\/example.com\/test
# )
echo json_encode(json_decode($json2)); # {"url":"http:\\\/\\\/example.com\\\/test"}

PHP json_encode has an option to prevent the PHP's default of escaping of backslashes:

# PHP
echo json_encode('/'); # "\/"
echo json_encode('/', JSON_UNESCAPED_SLASHES); # "/"

Ruby does not have a similar option to force escaping of slashes, but since a slash has no special meaning in JSON, we can just manually replace / with \/:

# Ruby
puts '/'.to_json # "/"
puts '/'.to_json.gsub('/', '\/') # "\/"

Single backslash for Ruby gsub replacement value?

You can represent a single backslash by either "\\" or '\\'. Try this in irb, where

 "\\".size

correctly outputs 1, showing that you indeed have only one character in this string, not 2 as you think. You can also do a

 puts "\\" 

Similarily, your example

puts("a\b".gsub("\", "\\"))

correctly prints

a\b

Ecape only single backslash and leave double backslashes

Like this:

"<p>  \\$%&;ñá< ></p>\r\n".gsub("\r","\\r").gsub("\n","\\n")

How to print backslash in single quoted string in ruby

So long as the strings share the same encoding, byte comparison would be elegant solution without the need for additional escaping.

str.bytes == other.bytes

To display a backslash, you simply escape it with a single backslash:

puts '\\'
\

Additionally, depending on your exact usage, could use the <=> operator:

(str <=> other).zero?

EDIT

To expand a little more, there is a difference in what is displayed to you if you just did something like this:

a = '\\'
p a
=> '\\'

This will show itself as two backslashes, but it is still in fact a single character, not two.

a = '\\'
a.bytes
=> [92] # ASCII code for a backslash (single byte)


Related Topics



Leave a reply



Submit