입력이 유효한 JSON 인지 판별하는 프로그램을 작성하십시오 .
-
입력 : ASCII 텍스트 :
[\x00-\x7F]*
참고 : ASCII에 문제가있는 경우 다른 인코딩을 자유롭게 사용하지만 게시물에 표시하십시오.
-
출력 :
Valid
또는Invalid
. 후행 줄 바꿈은 생략 될 수 있습니다. -
예:
$ echo '{"key": "value"}' | ./json-validate Valid $ echo '{key: "value"}' | ./json-validate Invalid
-
규칙 :
- JSON 구문 분석 라이브러리를 사용하지 마십시오.
- 부분적으로 올바른 솔루션은 허용되지만 눈살을 찌푸리게합니다.
- 테스트 스위트 점수를 게시하십시오 (아래 참조).
짧은 올바른 솔루션 승리.
프로그램에서 json-validate-test-suite.sh 를 실행 하고 점수를 게시하십시오. 예:
$ ./json-validate-test-suite.sh ./buggy-prog
fail: should be invalid: [ 0.1e ]
fail: should be invalid: [ 0.1e+-1 ]
fail: should be invalid: [ 0.1e-+1 ]
score: 297/300
자원:
- json.org- 따라 가기 쉬운 그림으로 JSON 문법을 간결하게 정의합니다.
- RFC 4627 -JSON 사양
- json-validate.c- 테스트 슈트를 통과하는 200 라인 구현.
JSON 문법은 다음과 같습니다.
json: object | array
object: '{' members? '}'
members: pair (',' pair)*
pair: string ':' value
array: '[' elements? ']'
elements: value (',' value)*
value: string
| number
| object
| array
| 'true'
| 'false'
| 'null'
string: '"' char* '"'
char: [^"\\\x00-\x1F]
| '\' escape
escape: ["\\/bfnrt]
| u [0-9A-Fa-f]{4}
number: '-'? (0 | [1-9][0-9]*) ('.' [0-9]+)? ([Ee] [+-]? [0-9]+)?
또한 공백은 6 개의 구조 문자 앞뒤에 나타날 수 있습니다. {}[]:,
ws = [\t\n\r ]*
다음을 명심하십시오.
- 와 같은 기능에주의하십시오
isspace()
. JSON의 공백은[\t\n\r ]
있지만,isspace()
또한 취급\v
(수직 탭)와\f
공간으로 (용지 공급). 단어가 그것을 가지고 있지만isdigit()
수 많은 것보다는 다만 동의를[0-9]
우리가 입력 ASCII에서 가정으로, 여기에 사용하는 것이 괜찮을 것 같네요. \x7F
는 기술적으로 제어 문자이지만 JSON RFC는이를 언급하지 않으며 (만 언급[\x00-\x1F]
) 대부분의 JSON 파서는\x7F
문자열의 문자 를 허용하는 경향이 있습니다. 이러한 모호성 때문에 솔루션은이를 수용할지 여부를 선택할 수 있습니다.
답변
PHP : 297 285 264 253 자
<?=preg_match(<<<'R'
~([\h
]*)({(?1)((("([^"\\\0- ]| |\\(["\\/bfnrt]|u[\dA-Fa-f]{4}))*")(?1):(?1)((?5)|-?(0|[1-9]\d*)(\.\d+)?([Ee][+-]?\d+)?|(?2)|true|false|null))(((?1),(?1))(?4))*)?}|\[(?1)((?8)((?13)(?8))*)?(?1)])(?1)\z~A
R
,`cat`)?'Valid':'Invalid';
점수 : 300/300
이것은 JSON 문법의 전체, 재귀 적 구현입니다.
nowdoc 구문 으로 인해 PHP ≥ 5.3에서만 작동 합니다 ( heredoc 은 모두 두 배가 필요했습니다 \
).
읽을 수있는 버전 :
(이것은 명명 된 캡처 그룹과 확장 구문을 가진 동일한 정규식입니다) :
#!/usr/bin/env php
<?php
$re = <<< 'RE'
~\A (?P<ws>[\t\n\r ])* (
(?P<object>\{ (?P>ws)*
(?P<members>
(?P<pair>
(?P<string>
"(?P<char>
[^"\\\x00-\x1F]
|\\(?P<escape>
["\\/bfnrt]
|u [0-9A-Fa-f]{4}
)
)*"
) (?P>ws)* : (?P>ws)* (?P<value>
(?P>string)
| (?P<number>-? (0 | [1-9][0-9]*) (\. [0-9]+)? ([Ee] [+-]? [0-9]+)? )
| (?P>object)
| (?P>array)
| true
| false
| null
)
) ( (?P>ws)* , (?P>ws)* (?P>pair) )*
)?
\})
|(?P<array>\[ (?P>ws)*
(?P<elements>
(?P>value) ( (?P>ws)* , (?P>ws)* (?P>value) )*
)?
(?P>ws)* \])
) (?P>ws)* \z~x
RE;
if (preg_match($re, stream_get_contents(STDIN))) {
echo 'Valid';
} else {
echo 'Invalid';
}
답변
파이썬 – 340 개 314 299 292 문자
import re,os
r=x=re.sub
z=r('0\.0+','0',r('e[+-]?0+|[\t\n\r]',' ',r(r'"(\\["nrtb\\/]|[^\\"\0-\37])*"','1',r(r'true|false|null|\\u\w{4}|[1-9]\d*','0',os.read(0,99)))))
while z!=x:z,x=r('\{(1:\d)?(,\\1)*\}|\[(-?\d(,-?\d)*)?\]','0',r(' *([][{}:,]) *','\\1',z)),z
print['Inv','V'][z=='0']+'alid'
점수
$ ./json-validate-test-suite.sh ./codegolf-474.py
score: 300/300
답변
스칼라-390 자
import scala.util.parsing.combinator.JavaTokenParsers
object J extends JavaTokenParsers{def j=o|a
def o:Parser[Any]="{"~repsep(p,",")~"}"
def p=s~":"~v
def a:Parser[Any]="["~repsep(v,",")~"]"
def v=s|o|a|"true"|"false"|"null"
def s=stringLiteral
def n=floatingPointNumber}
object Main{def main(a:Array[String]){print(if(J.parseAll(J.j,readLine()).successful)"Valid"else"Invalid")}}
파서 결합기를 사용하는 브레이 너가없는 솔루 톤입니다. 말 그대로 1 ~ 2 분 안에 작성되었습니다. 브라우저가 서버를 찾을 수 없다고 유효성 검사기 스크립트를 가져올 수 없습니다.