속성에 따옴표없이 JSON.stringify?


98

잘못된 JSON 형식 (속성 주위에 큰 따옴표 없음)을 사용하는 서비스를 사용하고 있습니다. 그래서 보내야합니다

{ name: "John Smith" } 대신에 { "name": "John Smith" }

이 형식은 내 서비스가 아니므로 변경할 수 없습니다.

누구든지 위와 같은 JavaScript 객체의 형식을 지정하는 stringify 라우팅을 알고 있습니까?

답변:


117

이 간단한 정규식 솔루션은 대부분의 경우 JSON 속성 이름을 인용 해제합니다.

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"}

극단적 인 경우 :

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

문제를 해결해 주신 Rob W에게 특별히 감사드립니다.

한계

일반적인 경우에는 앞서 언급 한 정규 표현식이 작동하지만 수학적으로는 정규 표현식을 사용하여 JSON 형식을 설명하는 것이 불가능하므로 모든 경우에서 작동합니다 (정규 표현식에서는 동일한 수의 중괄호를 계산할 수 없습니다.). 네이티브 함수를 통해 JSON 문자열을 공식적으로 구문 분석하고 다시 직렬화하여 따옴표를 제거하는 새 함수를 만듭니다.

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}}`;
}

예 : https://jsfiddle.net/DerekL/mssybp3k/


3
-1도 나도 아니었지만 질문을주의 깊게 읽어야합니다. OP는 객체를 구문 분석 / 평가가 아닌 (깨진) json으로 인코딩해야합니다.
— Salman A

7
@Derek이 방법은 신뢰할 수 없습니다 . 예를 들어, 다음 입력을 {"foo":"e\":bar"}받으십시오 . (유효한 JSON)은 {foo:e:bar"}(...)!
— Rob W

1
@Derek /\\\"/은 /\\"/. 전역 플래그를 추가하는 것을 잊지 마십시오. 그렇지 않으면 /\\"/g여러 \". 임의 문자의 경우 편집기가 질식 할 경우를 대비하여 리터럴 U + FFFF를 사용 하지 말고 이스케이프 시퀀스를 사용하십시오. 되돌리기위한 정규식은 /\uFFFF/g.
— Rob W

2
@Derek朕會功夫정규식을 /\"([^(\")"]+)\":/g단순화 할 수 있습니다 /"([^"]+)":/g참조 regex101.com/r/qnz0ld/2
— tanguy_k

1
@endriu이 경우 null 값에 대한 추가 검사를 추가하십시오.
— Derek 朕 會 功夫

18

이것은 당신이 찾고있는 간단한 Object toString 메소드 인 것 같습니다.

Node.js에서 이것은 util 객체를 사용하고 util.inspect (yourObject)를 호출하여 해결됩니다. 이것은 당신이 원하는 모든 것을 줄 것입니다. 방법 적용의 깊이를 포함하여 더 많은 옵션을 보려면이 링크를 따르십시오.http://nodejs.org/api/util.html#util_util_inspect_object_options

그래서, 당신이 찾고있는 것은 기본적으로 JSON 변환기가 아닌 객체 검사기입니다. JSON 형식은 모든 속성을 큰 따옴표로 묶어야 함을 지정합니다. 따라서 단순히 JSON 형식이 아니므로 원하는 작업을 수행하는 JSON 변환기가 없습니다. https://developer.mozilla.org/en-US/docs/Using_native_JSON

Object to string 또는 검사는 서버의 언어에 따라 필요한 것입니다.


1
정말 고마워! 이것이 바로 제가 찾던 것입니다. 나는 json을 사용하여 ws 서버를 통해 내 게임으로 데이터를 내보내고 믿거 나 말거나 속성 이름 주위의 추가 따옴표를 처리하지 않아도 엄청난 양의 데이터를 절약 할 수 있습니다! 명확히하기 위해 .toSource()nodejs 내에서도 잘 작동하지만 배열의 객체는 작동하지 않습니다. 는 util, 멋진 배열의 배열과 객체에 대한 작품을 검사 그것을 사랑 해요.
— NiCk Newman 2015

3
util.inspect()한 번에 여러 매개 변수를 설정하기 위해 Neo4j 쿼리에 개체를 작성하는 동안 나를 위해 멋지게 작동했습니다.
— agm1984

1
nodejs 링크에서 :> util.inspect () 메서드는 디버깅을위한 객체의 문자열 표현을 반환합니다. util.inspect의 출력은 언제든지 변경 될 수 있으며 프로그래밍 방식으로 의존해서는 안됩니다.
— Peter Roehlen

5

JSON 형식을 정의한 사람이 만든 파서 의 소스 코드를 볼 수 있습니다 . 함수 호출을 찾습니다 . 값을 따옴표로 묶습니다. 키는 326 및 338 행에 인용되어 있습니다 .json2.js quote

수정 후 라이브러리를 포함하지 마십시오. 대신 관련 ( stringify) 부분 만 취 하거나 적어도 JSON다른 것으로 교체하십시오 . FAKEJSON.

예를 들어, 오브젝트 FAKEJSON만 정의 stringify: http://jsfiddle.net/PYudw/


순수한 JavaScript로 할 수 있는데 왜 추가 라이브러리가 필요합니까?
— Derek 朕 會 功夫

이것은 좋은 생각입니다. 리포지토리를 포크하고 따옴표를 제거하고 JSON 개체의 이름을 FAILJSON과 같은 측면으로 변경하여 하여 실제 JSON 개체 또는 실제 JSON으로 작업하고 있지 않음을 .
— RichardTowers

@Derek 라이브러리 전체를 포함해서는 안됩니다. JSON.stringify부분 만 취하고 따옴표를 제거하십시오. 라이브러리는 JSON을 정의한 사람에 의해 생성되었으므로 결과가 매우 유효한 JSON임을 확신 할 수 있습니다.
— Rob W

이것이 최선의 방법 인 것 같습니다.
— Derek 朕 會 功夫

네, 데릭과 동의합니다. 그의 대체자는 잘 작동하지만, 나는 크로포드의 코드에 더 자신감을 느낍니다. derek lol에게 무례하지 않습니다. .toSource()잘 작동하지만 객체가 어수선한 배열에 있으면 포함하지 않습니다 (그리고 브라우저 호환성이 문제가되지 않는 노드에 있습니다 : P).이 방법을 사용할 것입니다 @RobW 감사합니다. :( 로딩 페이지에 붙어있을 수 있습니다
— 닉 뉴먼에게

3

JSONP와 함께 servive를 사용하십시오.이 형식을 사용할 때 제공한다고 생각합니다.

그렇지 않으면 왜이 표준을 준수해야하는지에 대한 좋은 주장을 포함하여 자세한 버그 보고서를 제출하십시오. 소스 문제를 제거하는 것 이외의 다른 해결책은 실제 해결책이 아닙니다.

빠르고 더러운 수정은 구문 분석하기 전에 정규식을 통해 문자열을 파이프하는 것입니다.

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

또는 보다 구문적인 구문 분석을 원하면 기존 javascript JSON 구문 분석기 (예 : 이와 같은 ) 를 조정하려고합니다 .




2

@Derek 朕 會 功夫이 방법을 공유 해주셔서 감사합니다. 객체 배열의 문자열 화를 지원하는 코드도 공유하고 싶습니다.

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
JSON.stringifyinstanceof Date도 사용해야 합니다. 이 null 인 'null'경우 에도 반환 합니다 obj_from_json.
— Far Dmitry

1
두 번째 if 조건을 다음과 같이 변경하여 @FarDmitry가 제기 한 포인트를 수정했습니다.if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null)
— Brunno Vodola Martins

2

사용하다 JSON5.stringify

JSON5 는 인용되지 않은 속성 키를 포함하여 ES5 구문을 허용하는 JSON의 상위 집합입니다 . JSON5 참조 구현 ( json5npm 패키지 )은 기본 제공 JSON5과 동일한 인수 및 의미를 가진 동일한 메서드를 가진 객체를 제공합니다.JSON 객체 합니다.

사용중인 서비스가이 라이브러리를 사용하고있을 가능성이 높습니다.


1

CSVJSON의 JSON Beautifier 에는 키에 따옴표를 넣는 옵션이 있습니다. 코드 만 원하는 경우 GitHub 저장소에서 복사 할 수 있습니다. 이에 대한 지원을 추가하기 위해 Douglas Crockford의 JSON2 를 수정 했습니다.


그냥 클릭 csvjson.com/json_beautifier ... 그리고 내가 기대했던 것보다 방법 다른 페이지를 가지고 hacked by AnoaGhost
— RedactedProfile

지금 정리했습니다. 불편을 드려 죄송합니다.
— Martin Drapeau
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.