Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby';到json';错误:UTF-8中的字节序列无效_Ruby On Rails_Json_Ruby_Encoding - Fatal编程技术网

Ruby on rails Ruby';到json';错误:UTF-8中的字节序列无效

Ruby on rails Ruby';到json';错误:UTF-8中的字节序列无效,ruby-on-rails,json,ruby,encoding,Ruby On Rails,Json,Ruby,Encoding,在rails控制台中,我得到: hash = {"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83"} #=> {"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83"} hash.to_json #>> ArgumentError: invalid byte sequence in UTF-8 from /home/edmodo/.rvm/gems/rub

在rails控制台中,我得到:

hash = {"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83"}
#=> {"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83"}
hash.to_json
#>> ArgumentError: invalid byte sequence in UTF-8
from /home/edmodo/.rvm/gems/ruby-2.3.0@one-eye/gems/activesupport-json_encoder-1.1.0/lib/active_support/json/encoding/active_support_encoder.rb:79:in `gsub'
“\xE1\x83”。to_json
不工作可能是由于非UTF-8字符

感谢您的帮助

如果将哈希转换为字符串,则它可以工作,但它会添加垃圾字符,如
u003E
,并带有大量额外的反斜杠

hash.to_s.to_json
#=> "\"{\\\"name\\\"=\\u003E\\\"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\\\\xE1\\\\x83\\\"}\""

这是因为您的输入字符串在UTF-8中包含无效的字节序列,错误消息正好说明了这一点。 你可以像这样检查它

hash['name'].valid_encoding?  # => false
基本上,您应该修复输入字符串,删除所有无效的字节序列字符;在您的示例中,它是
“\xE1\x83”

如果出于某种原因需要保留字节序列并将其编码为标准JSON,我认为必须首先对字符串进行编码,因为JSON不接受二进制数据,而只接受有效的UTF-8字符串。注意,就JSON而言,具有无效字节序列的字符串是二进制数据

在Rails中,可以使用Base64编码,如下所示:

hash['name'] = Base64.encode64 hash['name']
hash.to_json  # => a valid JSON
在解码时,必须指定编码,例如

hj = hash.to_json
Base64.decode64(JSON.parse(hj)['name']).force_encoding('UTF-8') # => Decoded string

注意,无论如何,在您的情况下,复制的字符串不是有效的UTF-8。但它将有助于在Rails控制台中显示。

这是因为您的输入字符串在UTF-8中包含无效的字节序列,正如错误消息准确地告诉您的那样。 你可以像这样检查它

hash['name'].valid_encoding?  # => false
基本上,您应该修复输入字符串,删除所有无效的字节序列字符;在您的示例中,它是
“\xE1\x83”

如果出于某种原因需要保留字节序列并将其编码为标准JSON,我认为必须首先对字符串进行编码,因为JSON不接受二进制数据,而只接受有效的UTF-8字符串。注意,就JSON而言,具有无效字节序列的字符串是二进制数据

在Rails中,可以使用Base64编码,如下所示:

hash['name'] = Base64.encode64 hash['name']
hash.to_json  # => a valid JSON
在解码时,必须指定编码,例如

hj = hash.to_json
Base64.decode64(JSON.parse(hj)['name']).force_encoding('UTF-8') # => Decoded string

注意,无论如何,在您的情况下,复制的字符串不是有效的UTF-8。但在Rails控制台中显示会有帮助。

如果您不怕丢失内容,可以使用以下解决方案:

pry(main)> 
{"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83".force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')}.to_json

=> "{\"name\":\"     \"}"

如果您不怕丢失内容,可以使用以下解决方案:

pry(main)> 
{"name"=>"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83".force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')}.to_json

=> "{\"name\":\"     \"}"
require'json'
def清除(字符串)
文本=“”
string.each|char{| char | text”სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83“}
hash.transform\u值!{|值|清除(值)}
将hash.to_json放入
{“姓名”:სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე"}
需要“json”
def清除(字符串)
文本=“”
string.each|char{| char | text”სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83“}
hash.transform_值!{| value | cleanup(value)}
将hash.to_json放入
{“姓名”:სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე"}

谢谢Stefan、Masa Sakano和Alexey Strizhak。你的建议对我帮助很大。
该字符串包含无效的字节序列字符,这是正确的。
我所做的只是保留有效的编码字符,如下所示-

"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83".chars.select(&:valid_encoding?).join
=> "სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე"
这将删除不完整/无效的字符,如“\xE1\x83”


再次感谢大家帮助我理解问题并提出解决方案。

谢谢Stefan、Masa Sakano和Alexey Strizhak。你们的建议对我帮助很大。 该字符串包含无效的字节序列字符,这是正确的。 我所做的只是保留有效的编码字符,如下所示-

"სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე\xE1\x83".chars.select(&:valid_encoding?).join
=> "სსიპ ოთარ ჩხეიძის სახელობის სოფელ ყე"
这将删除不完整/无效的字符,如“\xE1\x83”


再次感谢大家帮助我理解问题并提出解决方案。

垃圾?U+003E是
名称中的
字符=>
\xE1\x83
是3字节字符序列的前两个字节,因此它只是部分字符。解决方法是截断字符边界处的字符串,而不是中间的字符串。垃圾?U+003E是
名称中的
字符=>
\xE1\x83
是3字节字符序列的前两个字节,因此它只是一个部分字符。解决方法是截断字符边界处的字符串,而不是中间的字符串。如果我处于OP的位置,我会很高兴摆脱
“\xE1\x83”
在输入字符串中,但可能不想丢失它的任何其他部分…?我发现
无效::replace
而不是,或者除此之外,
undef::replace
将实现它。@Alexey,如果您愿意,请随时更新您的答案(这可能有助于未来的访问者)。如果我站在OP的立场上,我会很高兴摆脱输入字符串中的
“\xE1\x83”
,但可能不想丢失它的任何其他部分…?我发现
无效::替换
,而不是,或者除此之外,
未定义::替换
可以实现它。@Alexey,如果你愿意,请随时更新你的答案。@Alexey(这可能有助于未来的访问者)。
“ყე\xE1\x83“.encode('UTF-8',invalid::replace,undf::replace,replace:'')将更有效。
此外,如果原始字符串的编码为
ASCII-8BIT
,则解决方案不起作用,在这种情况下,任何字节都被视为有效。
”ყე\xE1\x83“.encode('UTF-8',invalid::replace,unde::replace,replace:'')将更有效。
此外,如果原始字符串的编码为
ASCII-8BIT
,则解决方案不起作用,在这种情况下,任何字节都被视为有效。