속성에 따옴표없이 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 형식을 정의한 사람이 만든 파서 의 소스 코드를 볼 수 있습니다 . 함수 호출을 찾습니다 . 값을 따옴표로 묶습니다. 키는 326338 행에 인용되어 있습니다 .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.