JSON.stringify mà không có dấu ngoặc kép trên thuộc tính?


95

Tôi đang sử dụng một dịch vụ sử dụng định dạng JSON không chính xác (không có dấu ngoặc kép xung quanh thuộc tính). Vì vậy, tôi cần gửi

{ name: "John Smith" } thay vì { "name": "John Smith" }

Không thể thay đổi định dạng này vì đây không phải là dịch vụ của tôi.

Có ai biết về định tuyến stringify để định dạng một đối tượng JavaScript như trên không?

Câu trả lời:


115

Giải pháp biểu thức chính quy đơn giản này hoạt động để hủy trích dẫn tên thuộc tính JSON trong hầu hết các trường hợp:

const object = { name: 'John Smith' };
const json = JSON.stringify(object);  // {"name":"John Smith"}
console.log(json);
const unquoted = json.replace(/"([^"]+)":/g, '$1:');
console.log(unquoted);  // {name:"John Smith"}

Trường hợp cực đoan:

var json = '{ "name": "J\\":ohn Smith" }'
json.replace(/\\"/g,"\uFFFF");  // U+ FFFF
json = json.replace(/"([^"]+)":/g, '$1:').replace(/\uFFFF/g, '\\\"');
// '{ name: "J\":ohn Smith" }'

Đặc biệt cảm ơn Rob W vì đã sửa nó.

Hạn chế

Trong các trường hợp bình thường, regexp nói trên sẽ hoạt động, nhưng về mặt toán học không thể mô tả định dạng JSON bằng một biểu thức chính quy để nó hoạt động trong mọi trường hợp (đếm cùng một số dấu ngoặc nhọn là không thể với regexp.) Do đó, tôi có tạo một hàm mới để xóa dấu ngoặc kép bằng cách phân tích cú pháp chính thức chuỗi JSON thông qua hàm gốc và sắp xếp lại nó:

function stringify(obj_from_json) {
    if (typeof obj_from_json !== "object" || Array.isArray(obj_from_json)){
        // not an object, stringify using native function
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    let props = Object
        .keys(obj_from_json)
        .map(key => `${key}:${stringify(obj_from_json[key])}`)
        .join(",");
    return `{${props}}`;
}

Ví dụ: https://jsfiddle.net/DerekL/mssybp3k/


3
-1 cũng không phải tôi, nhưng bạn phải đọc kỹ câu hỏi. OP cần mã hóa một đối tượng thành (bị hỏng) json, không phải phân tích cú pháp / đánh giá nó.
Salman A

7
@Derek Phương pháp này không đáng tin cậy . Ví dụ: lấy đầu vào này: {"foo":"e\":bar"}(JSON hợp lệ) trở thành {foo:e:bar"}(...)!
Rob W

1
@Derek /\\\"/có thể được đơn giản hóa thành /\\"/. Đừng quên thêm cờ chung /\\"/g, nếu không nó sẽ bị đứt trên các chuỗi có nhiều \". Đối với ký tự ngẫu nhiên, không bao giờ sử dụng U + FFFF theo nghĩa đen, trong trường hợp trình chỉnh sửa bị nghẹt, mà là một chuỗi thoát. Regex để hoàn nguyên sẽ trở thành /\uFFFF/g.
Rob W

2
@Derek 朕 會 功夫 regex của bạn /\"([^(\")"]+)\":/gcó thể được đơn giản hóa thành /"([^"]+)":/g, xem regex101.com/r/qnz0ld/2
tanguy_k

1
@endriu Trong trường hợp đó, chỉ cần thêm một kiểm tra bổ sung cho các giá trị null.
Derek 朕 會 功夫

18

Có vẻ như đây là một phương thức Object toString đơn giản mà bạn đang tìm kiếm.

Trong Node.js, điều này được giải quyết bằng cách sử dụng đối tượng use và gọi lệnh use.inspect (yourObject). Điều này sẽ cung cấp cho bạn tất cả những gì bạn muốn. theo liên kết này để có thêm tùy chọn bao gồm cả chiều sâu của việc áp dụng phương pháp. http://nodejs.org/api/util.html#util_util_inspect_object_options

Vì vậy, những gì bạn đang tìm kiếm về cơ bản là một trình kiểm tra đối tượng không phải là một trình chuyển đổi JSON. Định dạng JSON chỉ định rằng tất cả các thuộc tính phải được đặt trong dấu ngoặc kép. Do đó sẽ không có JSON chuyển đổi để làm những gì bạn muốn như mà chỉ đơn giản là không phải là một JSON format.Specs đây: https://developer.mozilla.org/en-US/docs/Using_native_JSON

Đối tượng để xâu chuỗi hoặc kiểm tra là những gì bạn cần tùy thuộc vào ngôn ngữ máy chủ của bạn.


1
Cảm ơn bạn rất nhiều! Điều này thật đúng với gì mà tôi đã tìm kiếm. Tôi sử dụng json để phát dữ liệu trên máy chủ ws vào trò chơi của mình và bạn có tin hay không, việc không phải đối mặt với dấu ngoặc kép xung quanh tên thuộc tính giúp tiết kiệm một lượng lớn dữ liệu! Chỉ cần làm rõ, .toSource()hoạt động tốt trong nodejs, nhưng không hoạt động đối với các đối tượng trong mảng. Việc utilkiểm tra hoạt động đối với các mảng và các đối tượng trong mảng thật tuyệt vời, hãy yêu nó.
NiCk Newman

3
util.inspect()vừa hoạt động tuyệt vời đối với tôi khi viết một đối tượng vào truy vấn Neo4j, để đặt nhiều tham số cùng một lúc.
agm1984,

1
Từ liên kết nodejs:> Phương thức use.inspect () trả về một biểu diễn chuỗi của đối tượng được dùng để gỡ lỗi. Đầu ra của use.inspect có thể thay đổi bất kỳ lúc nào và không nên phụ thuộc vào chương trình.
Peter Roehlen

5

Bạn có thể xem mã nguồn của trình phân tích cú pháp được tạo bởi người đã xác định định dạng JSON . Tìm kiếm các lệnh gọi hàm: chúng bao quanh một giá trị bằng dấu ngoặc kép. Các phím được trích dẫn ở dòng 326338 .json2.js quote

Không bao gồm thư viện sau khi sửa đổi. Thay vào đó, chỉ lấy phần ( stringify) có liên quan , hoặc ít nhất thay thế JSONbằng một cái gì đó khác, ví dụ. FAKEJSON.

Ví dụ: một đối tượng FAKEJSONchỉ được xác định stringify: http://jsfiddle.net/PYudw/


Tại sao bạn cần một thư viện bổ sung khi bạn có thể làm điều đó bằng JavaScript thuần túy?
Derek 朕 會 功夫

Đây là một ý tưởng tốt. Tôi sẽ fork repo, xóa các dấu ngoặc kép và đổi tên đối tượng JSON thành một thứ gì đó khó hiểu như FAILJSON để làm rõ rằng bạn không làm việc với đối tượng JSON thực hay JSON thực.
RichardTowers

@Derek Thư viện không nên được đưa vào toàn bộ. Chỉ lấy JSON.stringifymột phần và loại bỏ các dấu ngoặc kép. Vì thư viện được tạo bởi người đã định nghĩa JSON , chúng tôi có thể khá chắc chắn rằng kết quả là JSON rất hợp lệ.
Rob W

Có vẻ như đây là cách tiếp cận tốt nhất.
Derek 朕 會 功夫

Vâng, đồng ý với Derek. Mặc dù cầu thủ thay thế của anh ấy hoạt động tốt, nhưng tôi cảm thấy tự tin hơn với mã của creepford, không có sự thiếu tôn trọng với derek lol. .toSource()hoạt động tốt nhưng không bao gồm nếu đối tượng của bạn nằm trong mảng mà là một kẻ xấu (và tôi đang ở trên nút nên tính năng trình duyệt không phải là vấn đề: P) vì vậy tôi sẽ sử dụng phương pháp này, cảm ơn @RobW cũng vậy, liên kết jsfiddle có vẻ như bị mắc kẹt ở trang tải :(
NiCk Newman, 29/07/15

3

Hãy thử sử dụng servive với JSONP, tôi đoán họ cung cấp nó khi sử dụng định dạng này.

Nếu không, hãy gửi cho họ một báo cáo lỗi chi tiết bao gồm một lập luận tốt tại sao phải phù hợp với tiêu chuẩn. Bất kỳ giải pháp nào khác ngoài việc loại bỏ vấn đề nguồn không phải là giải pháp thực sự.

Cách khắc phục nhanh chóng có thể là chuyển chuỗi qua regex trước khi phân tích cú pháp:

var obj = JSON.parse(str.replace(/(\{|,)\s*(.+?)\s*:/g, '$1 "$2":'));

Hoặc bạn cố gắng điều chỉnh trình phân tích cú pháp javascript JSON hiện có (như trình này ) nếu bạn muốn phân tích cú pháp hơn.




2

@Derek 朕 會 功夫 Cảm ơn bạn đã chia sẻ phương pháp này, tôi muốn chia sẻ mã của mình hỗ trợ việc xâu chuỗi một mảng đối tượng.

export const stringifyObjectWithNoQuotesOnKeys = (obj_from_json) => {
    // In case of an array we'll stringify all objects.
    if (Array.isArray(obj_from_json)) {
        return `[${
                    obj_from_json
                        .map(obj => `${stringifyObjectWithNoQuotesOnKeys(obj)}`)
                        .join(",")
                }]` ;
    }
    // not an object, stringify using native function
    if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null){
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    return `{${
            Object
                .keys(obj_from_json)
                .map(key => `${key}:${stringifyObjectWithNoQuotesOnKeys(obj_from_json[key])}`)
                .join(",")
            }}`;
};

1
Bạn cũng nên sử dụng JSON.stringifycho instanceof Date. Cũng trả về 'null'nếu obj_from_jsonlà null.
Far Dmitry

1
Tôi chỉ cố định các điểm nêu ra bởi @FarDmitry bằng cách thay đổi thứ hai nếu điều kiện để trông như thế này:if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null)
Brunno Vodola Martins

2

Sử dụng JSON5.stringify

JSON5 là một tập hợp lớn của JSON cho phép cú pháp ES5, bao gồm các khóa thuộc tính chưa được trích dẫn . Việc triển khai tham chiếu JSON5 ( json5gói npm ) cung cấp một JSON5đối tượng có cùng các phương thức với cùng args và ngữ nghĩa với JSONđối tượng tích hợp sẵn.

Khả năng cao là dịch vụ bạn đang sử dụng đang sử dụng thư viện này.


1

Công cụ làm đẹp JSON của CSVJSON có tùy chọn để bỏ dấu ngoặc kép trên các khóa. Nếu bạn chỉ muốn mã, bạn có thể sao chép nó từ repo GitHub. Tôi đã sửa đổi JSON2 của Douglas Crockford để thêm hỗ trợ cho điều đó.


Chỉ cần nhấp vào csvjson.com/json_beautifier và nhận một cách trang khác hơn tôi mong đợi ... hacked by AnoaGhost
RedactedProfile

Đã làm sạch ngay bây giờ. Xin lỗi vì sự bất tiện.
Martin Drapeau,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.