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
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.
How to define a ruby array that contains a backslash(\) character?
There are some characters which are special and need to be escaped.
Like when you define a string
str = " this is test string \
and this contains multiline data \
do you understand the backslash meaning here \
it is being used to denote the continuation of line"
In a string defined in a double quotes "", if you need to have a double quote how would you doo that? "\"", this is why when you put a backslash in a string you are telling interpretor you are going to use some special characters and which are escaped by backslash. So when you read a "\" from a file it will be read as "\" this into a ruby string.
char = "\\"
char.length # => 1
I hope this helps ;)
Escape double and single backslashes in a string in Ruby
Just double-up every backslash, like so:
"\\\\servername\\some windows share\\folder 1\\folder2\\"
Related Topics
Rails - Aciverecord Use :Dependent => :Destroy on Condition
Rails Initializes Extremely Slow on Ruby 1.9.1
Regex to Validate String Having Only Characters (Not Special Characters), Blank Spaces and Numbers
Uploading a File to a Website with Ruby/Rails
Creating a Test Suite Using Ruby Minitest
Sorting a Hash in Ruby by Its Value First Then Its Key
How to Use Link_To to Link an Image and a Text
Is There a Bug in Ruby Lookbehind Assertions (1.9/2.0)
Detecting If This Is an Iframe Load or Direct
How to Programmatically Check If a Certificate Has Been Revoked
Array Typeerror: Can't Convert Fixnum into String
Installing Libyaml for Ruby on a MAC Osx (Lion)
Actioncable - Failed to Upgrade to Websocket in Production