JSON에서 줄 바꿈을 어떻게 처리합니까?


289

JSON을 생성했으며 JavaScript로 객체로 가져 오려고합니다. 계속 오류가 발생합니다. 내가 가진 것은 다음과 같습니다.

var data = '{"count" : 1, "stack" : "sometext\n\n"}';
var dataObj = eval('('+data+')');

이것은 나에게 오류를 준다 :

unterminated string literal

을 사용하면 Chrome에서 " ", Firefox 및 IE에서 " " 와 JSON.parse(data)유사한 오류 메시지가 표시 됩니다.Unexpected token ↵unterminated string literal

두 경우 모두 오류가 사라진 \n후 꺼내십시오 sometext. 왜 \n제조사 evalJSON.parse실패 했는지 알아낼 수 없습니다 .


19
eval 대신 실제 json 파서를 사용하십시오.
Eric

답변:


368

나는 이것이 당신이 원하는 것 같아요 :

var data = '{"count" : 1, "stack" : "sometext\\n\\n"}';

(문자열에서 "\"를 이스케이프 처리 (이중 "" "으로 전환)해야합니다. 그렇지 않으면 JSON 데이터가 아닌 JSON 소스의 개행 문자가됩니다.)


101
이것은 물론 정확하지만,이를 수행해야하는 이유를 추가하고 싶습니다. ietf.org/rfc/rfc4627.txt 의 JSON 사양 에는 섹션 2.5의 다음 문장이 포함되어 있습니다. "모든 유니 코드 문자는 이스케이프해야하는 문자를 제외한 따옴표 : 따옴표, 역진, 제어 문자 (U + 0000-U + 001F). " 개행은 제어 문자이므로 이스케이프되어야합니다.
다니엘 쿨만

1
www.json.org에 따르면 JSON은 문자열에서 제어 시퀀스 "\ n"을 받아들입니다. JSON.parse ([ ' "a \\ na"']] [1] .charCodeAt (); 마지막으로 확인했을 때 "Linefeed"인 10이 표시됩니다. --- BTW : 비명을 멈춰라!
BlaM

+ 1. JSON 인코딩을 이해하는 데 어려움이 있었지만 "JSON 데이터가 아닌 JSON 소스에서 줄 바꿈이 될 것입니다."
amucunguzi

44

당신은 대체하는 기능이 있어야합니다 \n\\n경우에 data문자열 리터럴되지 않습니다.

function jsonEscape(str)  {
    return str.replace(/\n/g, "\\\\n").replace(/\r/g, "\\\\r").replace(/\t/g, "\\\\t");
}

var data = '{"count" : 1, "stack" : "sometext\n\n"}';
var dataObj = JSON.parse(jsonEscape(data));

결과 dataObj

Object {count: 1, stack: "sometext\n\n"}

3
당신은 당신의 이스케이프 문자를 (예를 탈출해야합니다 .replace("\\n", "\\\\n")(예) 나는 여러 인스턴스를 교체 할 수 있도록 정규식을 사용하는 것이 좋습니다 것입니다 .replace(/\n/g, "\\\\n"))
musefan

2
왜 이스케이프 문자를 피해야합니까? 나는 .replace("\n", "\\n")일을 잘해야 한다는 것을 의미 합니다! 예를 들어 var test = [{"description":"Some description about the product. This can be multi-line text."}]; console.log(JSON.parse(test.replace(/\n/g, "\\n")));브라우저 콘솔에 다음과 같이 객체를 완벽하게 출력합니다.[{"description":"Some description about the product.\nThis can be multi-line text."}]
Fr0zenFyr

BTW, 위의 의견에서 원래 JSON 문자열에는 줄 바꿈이 있으며 이는 줄 바꿈에 대한 주석 포맷터에 의해 제거됩니다. 바꾸기 후 최종 출력은 줄 바꿈 문자 \n를 값에 삽입해야 함을 알 수 있습니다 .
Fr0zenFyr

1
-1이 답변은 먼저 유효하지 않은 JSON 문자열 (줄 바꿈이 제어 문자이므로)을 구성한 다음 일련의 불완전한 대체 (제어 문자가 3 개 이상)로 수정하려고합니다. 그런 다음 eval기능 을 사용하도록 관리 합니다. 공감 비 17 회 ???
Phil

1
이스케이프해야하는 따옴표는 어떻습니까?
독립형

8

사양에 따르면 http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf :

문자열은 따옴표 ( U+0022)로 묶인 일련의 유니 코드 코드 포인트 입니다. 이스케이프해야하는 문자 (따옴표 ( U+0022), 역 진법 ( U+005C) 및 제어 문자) U+0000를 제외한 모든 문자를 따옴표 안에 넣을 수 있습니다 U+001F. 일부 문자에는 두 문자 이스케이프 시퀀스 표현이 있습니다.

따라서 직접 전달 0x0A하거나 0x0C코드 를 작성할 수 없습니다 . 금지되어 있습니다! 사양은 일부 잘 정의 된 코드에 대한 이스케이프 시퀀스를 사용하는 제안 U+0000U+001F:

  • \f양식 피드 문자 ( U+000C)를 나타냅니다 .
  • \n줄 바꿈 문자 ( U+000A)를 나타냅니다 .

대부분의 프로그래밍 언어가 \인용에 사용하므로 이스케이프 구문을 피해야합니다 (이중 이스케이프-언어 / 플랫폼에 대해 한 번, JSON 자체에 대해 한 번).

jsonStr = "{ \"name\": \"Multi\\nline.\" }";

3

예를 들어 JSON 필드의 값을 쓸 때 서버에서 문자열을 이스케이프하고 클라이언트 브라우저에서 값을 검색 할 때 이스케이프를 해제 할 수 있습니다.

모든 주요 브라우저의 JavaScript 구현에는 unescape 명령이 있습니다.

예:

서버에서 :

response.write "{""field1"":""" & escape(RS_Temp("textField")) & """}"

브라우저에서 :

document.getElementById("text1").value = unescape(jsonObject.field1)

2

이 C # 함수를 사용하여 문자열을 이스케이프 처리 할 수 ​​있습니다.

http://www.aspcode.net/C-encode-a-string-for-JSON-JavaScript.aspx

public static string Enquote(string s)  
{ 
    if (s == null || s.Length == 0)  
    { 
        return "\"\""; 
    } 
    char         c; 
    int          i; 
    int          len = s.Length; 
    StringBuilder sb = new StringBuilder(len + 4); 
    string       t; 

    sb.Append('"'); 
    for (i = 0; i < len; i += 1)  
    { 
        c = s[i]; 
        if ((c == '\\') || (c == '"') || (c == '>')) 
        { 
            sb.Append('\\'); 
            sb.Append(c); 
        } 
        else if (c == '\b') 
            sb.Append("\\b"); 
        else if (c == '\t') 
            sb.Append("\\t"); 
        else if (c == '\n') 
            sb.Append("\\n"); 
        else if (c == '\f') 
            sb.Append("\\f"); 
        else if (c == '\r') 
            sb.Append("\\r"); 
        else 
        { 
            if (c < ' ')  
            { 
                //t = "000" + Integer.toHexString(c); 
                string t = new string(c,1); 
                t = "000" + int.Parse(tmp,System.Globalization.NumberStyles.HexNumber); 
                sb.Append("\\u" + t.Substring(t.Length - 4)); 
            }  
            else  
            { 
                sb.Append(c); 
            } 
        } 
    } 
    sb.Append('"'); 
    return sb.ToString(); 
} 

3
이것이 왜 탈출 >합니까?
아무것도 불필요

0

이 함수를 사용하여 JSON 데이터를 구문 분석하기 위해 데이터에서 줄 바꿈 또는 다른 문자를 제거했습니다.

function normalize_str($str) {

    $invalid = array(
        'Š'=>'S', 'š'=>'s',  'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z',
        'Č'=>'C', 'č'=>'c',  'Ć'=>'C',  'ć'=>'c',  'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A',
        'Ä'=>'A', 'Å'=>'A',  'Æ'=>'A',  'Ç'=>'C',  'È'=>'E', 'É'=>'E', 'Ê'=>'E', 'Ë'=>'E',
        'Ì'=>'I', 'Í'=>'I',  'Î'=>'I',  'Ï'=>'I',  'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
        'Õ'=>'O', 'Ö'=>'O',  'Ø'=>'O',  'Ù'=>'U',  'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y',
        'Þ'=>'B', 'ß'=>'Ss', 'à'=>'a',  'á'=>'a',  'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a',
        'æ'=>'a', 'ç'=>'c',  'è'=>'e',  'é'=>'e',  'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i',
        'î'=>'i', 'ï'=>'i',  'ð'=>'o',  'ñ'=>'n',  'ò'=>'o', 'ó'=>'o', 'ô'=>'o', 'õ'=>'o',
        'ö'=>'o', 'ø'=>'o',  'ù'=>'u',  'ú'=>'u',  'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
        'ÿ'=>'y', 'Ŕ'=>'R',  'ŕ'=>'r',
        "`" => "'", "´" => "'",  '"' => ',',  '`' => "'",
        '´' => "'", '"' => '\"', '"' => "\"", '´' => "'",
        "&acirc;€™" => "'",
        "{" => "",
        "~" => "",  "–" => "-",  "'" => "'",  "     " => " ");

    $str = str_replace(array_keys($invalid), array_values($invalid), $str);

    $remove = array("\n", "\r\n", "\r");
    $str = str_replace($remove, "\\n", trim($str));

    //$str = htmlentities($str, ENT_QUOTES);

    return htmlspecialchars($str);
}

echo normalize_str($lst['address']);

9
대부분의 언어에는 고유 한 매핑 기능을 작성하는 것보다 유니 코드 문자열에서 악센트를 제거하는 더 좋은 방법이 있습니다. python의 예는 다음 질문을 참조하십시오. stackoverflow.com/questions/517923/…
MiniQuark

나중에 다른 언어로 특수 문자를 제어하는 ​​많은 방법이 있습니다.
ShivarajRH

2
그것은 일반적으로 그들을 제거하는 모든 종류의 나쁜 것입니다. XML 숫자 문자 참조로 인코딩 한 다음 수신 끝에서 디코딩하십시오.
Annarfych

0

JSON.stringify

JSON.stringify(`{ 
  a:"a"
}`)

위의 문자열을

"{ \n      a:\"a\"\n    }"

여기에 언급 된 바와 같이

json stringify

이 함수는 입력 문자열의 시작과 끝에 큰 따옴표를 추가하고 특수 JSON 문자를 이스케이프합니다. 특히, 줄 바꿈은 \ n 문자로 대체되고 탭은 \ t 문자로 대체되고 백 슬래시는 두 개의 백 슬래시로 대체되며 백 슬래시는 각 인용 부호 앞에 배치됩니다.


4
이것은 기존의 여덟 가지 답변이있는 11 살짜리 질문에 대한 코드 전용 답변입니다. 코드를 설명하고 질문의 새로운 측면이 무엇을 해결하는지, 그리고 시간이 지남에 따라 새로운 버전의 릴리스가 답변에 영향을 미치는지 설명하는 것이 유용합니다.
Jason Aller

-1

json_encode (PHP 5에서 사용 가능)를 에뮬레이트하기 위해 PHP 4에서 클래스를 만드는 동안이 문제가 발생했습니다. 내가 생각해 낸 것은 다음과 같습니다.

class jsonResponse {
    var $response;

    function jsonResponse() {
        $this->response = array('isOK'=>'KO', 'msg'=>'Undefined');
    }

    function set($isOK, $msg) {
        $this->response['isOK'] = ($isOK) ? 'OK' : 'KO';
        $this->response['msg'] = htmlentities($msg);
    }

    function setData($data=null) {
        if(!is_null($data))
            $this->response['data'] = $data;
        elseif(isset($this->response['data']))
            unset($this->response['data']);
    }

    function send() {
        header('Content-type: application/json');
        echo '{"isOK":"' . $this->response['isOK'] . '","msg":' . $this->parseString($this->response['msg']);
        if(isset($this->response['data']))
            echo ',"data":' . $this->parseData($this->response['data']);
        echo '}';
    }

    function parseData($data) {
        if(is_array($data)) {
            $parsed = array();
            foreach ($data as $key=>$value)
                array_push($parsed, $this->parseString($key) . ':' . $this->parseData($value));
            return '{' . implode(',', $parsed) . '}';
        }
        else
            return $this->parseString($data);
    }

    function parseString($string) {
            $string = str_replace("\\", "\\\\", $string);
            $string = str_replace('/', "\\/", $string);
            $string = str_replace('"', "\\".'"', $string);
            $string = str_replace("\b", "\\b", $string);
            $string = str_replace("\t", "\\t", $string);
            $string = str_replace("\n", "\\n", $string);
            $string = str_replace("\f", "\\f", $string);
            $string = str_replace("\r", "\\r", $string);
            $string = str_replace("\u", "\\u", $string);
            return '"'.$string.'"';
    }
}

나는 여기에 언급 된 규칙을 따랐다 . 필요한 것만 사용했지만 사용중인 언어로 필요에 맞게 조정할 수 있다고 생각합니다. 내 경우의 문제는 원래 생각했던 줄 바꿈이 아니라 탈출하지 않은 것에 관한 것이었다. 나는 이것이 내가 뭘 잘못했는지 알아 낸 작은 두통에서 다른 누군가를 막기를 바랍니다.


2
json.org에 지정된 제어 문자에 대한 6 개의 속기는 모든 제어 문자의 전체 목록이 아닙니다. 결과적으로이 함수는 유효하지 않은 JSON을 생성 할 수 있습니다.
Phil

-5

나는 당신에게 질문을 이해, 그것은 당신이 당신의 코드로 JSON을 복사하여 붙여 넣을 수 있기 때문에 직접 JSON을 구문 분석에 대한 아니다 -이 후 그냥 JSON가 직접 복사의 경우 그렇다면 dataObj따옴표로 포장하지 않고 변수 (팁 : eval==evil)

var dataObj = {"count" : 1, "stack" : "sometext\n\n"};

console.log(dataObj);

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.