to_json 格式化后如何在 Ruby 字符串中保留单个反斜杠?
How to keep single backslash in Ruby string after to_json formating?
我需要对一些包含 URL 字符串的散列进行编码。我使用 to_json 方法,每个斜杠前需要反斜杠(因为 PHP 打印这样的字符串)。
例如:
hash = {"url":"http:\/\/example.com\/test"}
hash.to_json
结果是
{:url=>"http:\/\/example.com\/test"}
虽然我需要(和 PHP 的 json_encode returns 带有单个反斜杠的字符串)。
{:url=>"http:\/\/example.com\/test"}
在编码的情况下,保持 PHP 中的字符串非常重要。因为带有双反斜杠和单反斜杠的字符串会得到不同的结果。
更新:
问题不在于沟通。我需要使用 HMAC (SHA384) 对 JSON 进行编码。当我使用 URL 字符串时,PHP 和 Ruby 的结果不同。如果字符串不包含反斜杠,一切正常...
PHP 实现引入了反斜杠。 JSON 使用 PHP 看起来是 {"url":"http:\/\/example.com\/test"}
而 Ruby 的 JSON 是 {"url":"http:\/\/example.com\/test"}
如果您不想处理转义反斜杠,请在字符串周围使用单引号。
hash = { url: 'http:\/\/example.com\/test' }
json = hash.to_json
puts json
# => {"url":"http:\/\/example.com\/test"}
快速提醒:在 JSON 中,反斜杠需要转义,因为它们被视为控制字符。
这样,当 PHP 解析此 JSON 文档时,您将获得在每个斜杠之前带有一个反斜杠的字符串。
你的问题背后的问题可能是真正的问题。我不确定,因为你的问题对我来说不是很清楚,所以我在这里 guess/assumption 回答。
我这里的假设是你想在 ruby 和 php 之间进行通信,json。
好吧,在那种情况下你不必有问题(反斜杠)。
设ruby.to_json(JSON.generate(..))和JSON.parse(..) 求解 ruby 部分,让 json_encode() 和 json_decode() 解决 php 部分,你就完成了。
所以在ruby中:
- 不要使用额外的 escaping-backslashes,让 .to_json 为您解决
- 使用您在浏览器中输入的文字 url 字符串,如下所示:
hash = {"url":"http://example.com/test"} # hash is a ruby object
puts hash.to_json # => {"url":"http://example.com/test"} is JSON (string)
然后在php:
var_dump( json_decode('{"url": "http://example.com/test"}') );
给你:
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
var_dump( json_decode('{"url": "http:\/\/example.com\/test"}') );
给你:
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
注意 JSON 两个字符串最终都在 PHP 中被正确解析并最终成为一个普通的 PHP 对象
像下面这样尝试
hash = {"url":"http:\/\/example.com\/test"}
hash[:url] = hash[:url].delete("\")
hash.to_json #"{\"url\":\"http://example.com/test\"}"
希望对您有所帮助
抱歉,您手上的问题似乎确实存在。关键是:Why is the slash an escapable character in JSON? and its duplicate target, JSON: why are forward slashes escaped?。由于非转义斜线和转义斜线都允许,Ruby选择不转义,PHP选择转义,两种做法都是正确的。
(旁白:谈论这个有点复杂,因为 \
是字符串文字和 JSON 字符串的转义字符。因此,在这个答案中,我注意 puts
(或 echo
/print_r
)所有值,以查看没有字符串文字反斜杠转义的字符串,只有字符串中实际存在的反斜杠.)
因此,JSON {"url":"http:\/\/example.com\/test"}
是 Ruby 散列 { 'url' => 'http://example.com/test' }
的表示,其中斜线被转义(如 PHP 的 json_encode
会做)。 Ruby 的 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"}
另一方面,{"url":"http:\/\/example.com\/test"}
(在Ruby和PHP中表示为字符串'{"url":"http:\\/\\/example.com\\/test"}'
)是Ruby散列{ 'url' => 'http:\/\/example.com\/test' }
,其中有实际的反斜杠,但斜杠没有转义。 PHP 的 json_encode
会将此值呈现为 {"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
有一个选项可以防止 PHP 默认转义反斜杠:
# PHP
echo json_encode('/'); # "\/"
echo json_encode('/', JSON_UNESCAPED_SLASHES); # "/"
Ruby 没有类似的强制转义斜线的选项,但是由于斜线在 JSON 中没有特殊含义,我们可以手动将 /
替换为 \/
:
# Ruby
puts '/'.to_json # "/"
puts '/'.to_json.gsub('/', '\/') # "\/"
我需要对一些包含 URL 字符串的散列进行编码。我使用 to_json 方法,每个斜杠前需要反斜杠(因为 PHP 打印这样的字符串)。 例如:
hash = {"url":"http:\/\/example.com\/test"}
hash.to_json
结果是
{:url=>"http:\/\/example.com\/test"}
虽然我需要(和 PHP 的 json_encode returns 带有单个反斜杠的字符串)。
{:url=>"http:\/\/example.com\/test"}
在编码的情况下,保持 PHP 中的字符串非常重要。因为带有双反斜杠和单反斜杠的字符串会得到不同的结果。
更新: 问题不在于沟通。我需要使用 HMAC (SHA384) 对 JSON 进行编码。当我使用 URL 字符串时,PHP 和 Ruby 的结果不同。如果字符串不包含反斜杠,一切正常...
PHP 实现引入了反斜杠。 JSON 使用 PHP 看起来是 {"url":"http:\/\/example.com\/test"}
而 Ruby 的 JSON 是 {"url":"http:\/\/example.com\/test"}
如果您不想处理转义反斜杠,请在字符串周围使用单引号。
hash = { url: 'http:\/\/example.com\/test' }
json = hash.to_json
puts json
# => {"url":"http:\/\/example.com\/test"}
快速提醒:在 JSON 中,反斜杠需要转义,因为它们被视为控制字符。
这样,当 PHP 解析此 JSON 文档时,您将获得在每个斜杠之前带有一个反斜杠的字符串。
你的问题背后的问题可能是真正的问题。我不确定,因为你的问题对我来说不是很清楚,所以我在这里 guess/assumption 回答。
我这里的假设是你想在 ruby 和 php 之间进行通信,json。
好吧,在那种情况下你不必有问题(反斜杠)。
设ruby.to_json(JSON.generate(..))和JSON.parse(..) 求解 ruby 部分,让 json_encode() 和 json_decode() 解决 php 部分,你就完成了。
所以在ruby中:
- 不要使用额外的 escaping-backslashes,让 .to_json 为您解决
- 使用您在浏览器中输入的文字 url 字符串,如下所示:
hash = {"url":"http://example.com/test"} # hash is a ruby object
puts hash.to_json # => {"url":"http://example.com/test"} is JSON (string)
然后在php:
var_dump( json_decode('{"url": "http://example.com/test"}') );
给你:
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
var_dump( json_decode('{"url": "http:\/\/example.com\/test"}') );
给你:
object(stdClass)#1 (1) {
["url"]=>
string(23) "http://example.com/test"
}
注意 JSON 两个字符串最终都在 PHP 中被正确解析并最终成为一个普通的 PHP 对象
像下面这样尝试
hash = {"url":"http:\/\/example.com\/test"}
hash[:url] = hash[:url].delete("\")
hash.to_json #"{\"url\":\"http://example.com/test\"}"
希望对您有所帮助
抱歉,您手上的问题似乎确实存在。关键是:Why is the slash an escapable character in JSON? and its duplicate target, JSON: why are forward slashes escaped?。由于非转义斜线和转义斜线都允许,Ruby选择不转义,PHP选择转义,两种做法都是正确的。
(旁白:谈论这个有点复杂,因为 \
是字符串文字和 JSON 字符串的转义字符。因此,在这个答案中,我注意 puts
(或 echo
/print_r
)所有值,以查看没有字符串文字反斜杠转义的字符串,只有字符串中实际存在的反斜杠.)
因此,JSON {"url":"http:\/\/example.com\/test"}
是 Ruby 散列 { 'url' => 'http://example.com/test' }
的表示,其中斜线被转义(如 PHP 的 json_encode
会做)。 Ruby 的 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"}
另一方面,{"url":"http:\/\/example.com\/test"}
(在Ruby和PHP中表示为字符串'{"url":"http:\\/\\/example.com\\/test"}'
)是Ruby散列{ 'url' => 'http:\/\/example.com\/test' }
,其中有实际的反斜杠,但斜杠没有转义。 PHP 的 json_encode
会将此值呈现为 {"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
有一个选项可以防止 PHP 默认转义反斜杠:
# PHP
echo json_encode('/'); # "\/"
echo json_encode('/', JSON_UNESCAPED_SLASHES); # "/"
Ruby 没有类似的强制转义斜线的选项,但是由于斜线在 JSON 中没有特殊含义,我们可以手动将 /
替换为 \/
:
# Ruby
puts '/'.to_json # "/"
puts '/'.to_json.gsub('/', '\/') # "\/"