2012-10-03 38 views
16

Tôi đang chuyển một số JSON đến một máy chủ thông qua một kịch bản (không phải của tôi) chấp nhận JSON như một chuỗi.Làm cách nào để thoát khỏi một dấu nháy đơn trong Ruby?

Một số nội dung của JSON chứa các trích dẫn đơn nên tôi muốn đảm bảo rằng bất kỳ dấu nháy đơn nào đều được thoát trước khi được chuyển đến tập lệnh.

Tôi đã thử những điều sau đây:

> irb 
> 1.9.3p194 :001 > x = "that's an awesome string" 
> => "that's an awesome string" 
> 1.9.3p194 :002 > x.sub("'", "\'") 
> => "that's an awesome string" 
> 1.9.3p194 :003 > x.sub("'", "\\'") 
> => "thats an awesome strings an awesome string" 

nhưng dường như không thể có được đúng cú pháp.

+3

thế nào là giá trị "được chuyển"? Bởi vì * đó * có vẻ giống như lỗ hổng; JSON xử lý các trích dẫn nhúng chỉ tốt, và một khi nó là * bên trong * một chuỗi Ruby, nó không quan trọng. –

+0

Nếu "thông qua tập lệnh" có nghĩa là quá trình con, hãy mở nó * mà không * tạo một vỏ con sẽ sửa vấn đề này hoàn toàn trong các hệ thống giống Unix. (Tôi không chắc chắn nếu các công cụ Win32 là đủ vá cho điều này vô nghĩa.) –

+2

'x.sub ("'", "\\\\" ")' làm những gì bạn đang cố gắng làm. Nhưng con đường của Người Tín là cách đúng đắn để giải thích. – Zabba

Trả lời

3

Tại sao bạn không sử dụng đá quý JSON?

require 'json' 
some_object = {'a string' => "this isn't escaped because JSON handles it.", 'b' => 2} 

puts some_object.to_json 
=> {"a string":"this isn't escaped because JSON handles it.","b":2} 

Và một ví dụ khứ hồi:

require 'pp' 
pp JSON[some_object.to_json] 
=> { 
    "a string" => "this isn't escaped because JSON handles it.", 
     "b" => 2 
} 

Và một ví dụ với hai dấu ngoặc kép:

some_object = { 
    'a string'  => "this isn't escaped because JSON handles it.", 
    'another string' => 'double-quotes get "escaped"' 
} 
puts some_object.to_json 
=> { 
      "a string" => "this isn't escaped because JSON handles it.", 
     "another string" => "double-quotes get \"escaped\"" 
    } 
+0

Không sử dụng đá quý JSON vì nó không thực sự cần thiết và nó không chạy trên máy khách của tôi. –

26

Lý do sub("'", "\'") không hoạt động được vì "\'" cũng giống như "'" . Trong dấu ngoặc kép, việc thoát khỏi một dấu nháy đơn là tùy chọn.

Lý do sub("'", "\\'") không hoạt động là vì "\\'" mở rộng thành dấu gạch chéo ngược theo sau là một dấu trích dẫn duy nhất. Trong các đối số sub hoặc gsub, dấu gạch chéo ngược theo sau là một số ký tự có ý nghĩa đặc biệt có thể so sánh với biến toàn cục tương ứng. Đặc biệt trong trường hợp này, biến toàn cầu $' giữ chuỗi con sau điểm kết hợp cuối cùng. "\\'" của bạn trong phạm vi sub hoặc gsub vị trí đối số đề cập đến một điều tương tự. Để tránh ước đặc biệt này, bạn nên đặt các chuỗi thay thế trong một khối thay vì một cuộc tranh cãi, và kể từ khi bạn muốn để phù hợp với không chỉ một, bạn nên sử dụng gsub thay vì sub:

gsub("'"){"\\'"} 
+0

Than ôi không thực sự hoạt động –

+0

@DaveSag Nó hoạt động. – sawa

+0

Không - điều đó cho '" đó là một chuỗi tuyệt vời "' –

1

Nó có khả năng nếu bạn đang cố gắng thoát khỏi một dấu nháy đơn (dấu nháy đơn), bạn cũng muốn thoát khỏi dấu nháy kép. (Điều này sẽ áp dụng cho Javascript/JSON)

Cách dễ nhất là sử dụng escape_javascripthttp://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html nó "Trả về vận chuyển ký tự và dấu nháy đơn và kép cho phân đoạn JavaScript".

LƯU Ý chỉ hoạt động với Ruby on Rails, không phải là Ruby thuần túy. Tuy nhiên bạn có thể làm cho một polyfill cho đồng bằng của Ruby sử dụng một cái gì đó như thế này:

JS_ESCAPE_MAP = { '\\' => '\\\\', '</' => '<\/', "\r\n" => '\n', "\n" => '\n', "\r" => '\n', '"' => '\\"', "'" => "\\'" } 

def escape_javascript(javascript) 
    if javascript 
    result = javascript.gsub(/(\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] } 
    else 
    '' 
    end 
end 
1

Hãy thử cách này, sử dụng dấu chéo ngược để thoát:

puts 'sean\'s' 

sản lượng nên là:

sean's 
Các vấn đề liên quan