Slash and Backslash in Ruby

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('/', '\/') # "\/"

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)

How to print a string with a backward slash in Ruby

UPDATED answer:

escape token '\' is always working in plain ruby code, but not always working in "ruby console". so I suggest you write a unit test:

# escape_token_test.rb 
require 'test/unit'
class EscapeTokenTest < Test::Unit::TestCase
def test_how_to_escape
hi = "hi\\backslash"
puts hi
end
end

and you will get result as:

hi\backslash

and see @pst's comment.

How to gsub slash / with back slash and slash \/ in ruby

Yes

irb(main):028:0> (t = x.gsub("/", "\\/")) && nil
=> nil
irb(main):029:0> t
=> "\\/foo\\/bar\\/dir"
irb(main):030:0> puts t
\/foo\/bar\/dir
=> nil

Your first example actually did what you wanted, but the .inspect method that irb is using is escaping backslashes, so it looked like there were extras. If you had used puts you would have seen the real result.

How to split a string by slash in ruby

Problem

Your tmp variable is enclosed in double-quotes, and contains a backslash which is being interpreted as an escape rather than a character literal. You can see this easily by simply pasting your string into a REPL like irb:

"DESKTOP-AHDESI\Username" #=> "DESKTOP-AHDESIUsername"

You need to handle the backslash specially in both your String methods.

Solution

One way to handle this is to use Ruby's alternate quoting mechanism. For example:

%q(DESKTOP-AHDESI\Username).split '\\'   #=> ["DESKTOP-AHDESI", "Username"]

This may not help you directly, though.
Wherever the value from tmp is coming from, you need to refactor the code to ensure that your String is properly escaped before you assign it to your variable, or otherwise pre-process it. String#dump won't really help much if the value you're assigning is unescaped before assignment, so you're going to have to fix this in whatever code you're using to generate or grab the string in the first place.

I try to replace the backward slash with forward slash using gsub but it's not working

The problem is not with the #gsub, but with the string construction itself:

"C:\WATIR\gopal\**" # => "C:WATIRgopal**"

\ is used for escaping character. \W for example will try go escape the W character, instead of make two characters - \ and W. One way to fix it is to escape the escaping with another \:

"C:\\WATIR\\gopal\\**" # => "C:\\WATIR\\gopal\\**"

The better way is to use single quotes, where \ has no special meaning:

'C:\WATIR\gopal\**' # => "C:\\WATIR\\gopal\\**"

Additionally, prefer #tr over #gsub when you want to replace a single character with another:

'C:\WATIR\gopal\**'.tr('\\', '/') # => "C:/WATIR/gopal/**"

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 ;)



Related Topics



Leave a reply



Submit