문제

JSON 객체를 C#의 문자열 배열로 구문 분석하려고합니다. JSON 객체에서 배열을 추출 할 수 있지만 배열 문자열을 개별 개체 배열로 분할 할 수는 없습니다.

내가 가진 것은이 테스트 문자열입니다.

string json = "{items:[{id:0,name:\"Lorem Ipsum\"},{id:1,name" 
            + ":\"Lorem Ipsum\"},{id:2,name:\"Lorem Ipsum\"}]}";

지금은 다음과 같은 정규 표현식을 사용하여 항목을 개별 객체로 나누고 있습니다. 지금은 두 번째 문제로 문제를 해결할 때까지 2 개의 별도의 정규 표현식입니다.

Regex arrayFinder = new Regex(@"\{items:\[(?<items>[^\]]*)\]\}"
                                 , RegexOptions.ExplicitCapture);
Regex arrayParser = new Regex(@"((?<items>\{[^\}]\}),?)+"
                                 , RegexOptions.ExplicitCapture);

그만큼 arrayFinder Regex는 내가 기대하는 방식으로 작동하지만 이해하지 못하는 이유로 arrayParser Regex는 전혀 작동하지 않습니다. 내가 원하는 것은 개별 항목을 자신의 문자열로 나누기 때문에 다음과 같은 목록을 얻는 것입니다.

{id:0,name:"Lorem Ipsum"}
{id:1,name:"Lorem Ipsum"}
{id:2,name:"Lorem Ipsum"}

이 목록이 string[] 배열 또는 a Group 또는 Match 컬렉션은 중요하지 않지만 물체를 분할하는 방법에 대해 혼란스러워합니다. 사용 arrayParser 그리고 json 위에 선언 된 문자열은 운이없는이 코드를 시도했습니다.

string json = "{items:[{id:0,name:\"Lorem Ipsum\"},{id:1,name" 
            + ":\"Lorem Ipsum\"},{id:2,name:\"Lorem Ipsum\"}]}";

Regex arrayFinder = new Regex(@"\{items:\[(?<items>[^\]]*)\]\}"
                                 , RegexOptions.ExplicitCapture);
Regex arrayParser = new Regex(@"((?<items>\{[^\}]\}),?)+"
                                 , RegexOptions.ExplicitCapture);

string array = arrayFinder.Match(json).Groups["items"].Value;
// At this point the 'array' variable contains: 
// {id:0,name:"Lorem Ipsum"},{id:1,name:"Lorem Ipsum"},{id:2,name:"Lorem Ipsum"}

// I would have expected one of these 2 lines to return 
// the array of matches I'm looking for
CaptureCollection c = arrayParser.Match(array).Captures;
GroupCollection g = arrayParser.Match(array).Groups;

아무도 내가 뭘 잘못하고 있는지 볼 수 있습니까? 나는 이것에 완전히 붙어있다.

도움이 되었습니까?

해결책

균형 잡힌 괄호는 말 그대로 정규식으로 처리 할 수없는 언어의 교과서 예입니다. JSON은 본질적으로 균형 잡힌 괄호와 다른 많은 것들이 있으며, 버팀대는 파렌으로 대체됩니다. 에서 공식 언어의 계층 구조, JSON은 상황이없는 언어입니다. 정규 표현식은 컨텍스트가없는 언어를 구문 분석 할 수 없습니다.

일부 시스템은 균형 잡힌 표현식을 처리하는 정규 표현식에 대한 확장을 제공합니다. 그러나 그들은 모두 못생긴 해킹, 모두 포송 할 수 없으며 궁극적으로 업무를위한 잘못된 도구입니다.

전문적인 작업에서는 거의 항상 기존 JSON 파서를 사용합니다. 교육 목적으로 직접 굴려 보려면 + - * / ()를 지원하는 간단한 산술 문법으로 시작하는 것이 좋습니다. (JSON은 복잡하지는 않지만 첫 번째 시도가 필요한 것보다 더 어렵게 만드는 탈출 규칙이 있습니다.) 기본적으로, 당신은 다음을 필요로합니다.

  1. 언어를 기호의 알파벳으로 분해하십시오
  2. 언어를 인식하는 상징의 관점에서 문맥이없는 문법을 작성하십시오.
  3. 문법을 Chomsky 정상 형태로 변환하거나 5 단계를 쉽게 만들기에 충분히 가까이
  4. 원시 텍스트를 입력 알파벳으로 변환하는 Lexer를 작성하십시오.
  5. Lexer의 출력을 취하고 구문 분석하고 어떤 종류의 출력을 생성하는 재귀 하강 파서를 작성하십시오.

이것은 거의 모든 대학에서 전형적인 3 학년 CS 과제입니다.

다음 단계는 재귀 파서에서 스택 오버 플로우를 트리거하는 데 JSON 문자열이 얼마나 복잡한 지 알아내는 것입니다. 그런 다음 쓸 수있는 다른 유형의 파서를 살펴보면 실제 세계에서 문맥이없는 언어를 구문 분석 해야하는 사람이 파서를 손으로 쓰는 대신 YACC 또는 ANTLR과 같은 도구를 사용하는 이유를 이해할 수 있습니다.

그것이 당신이 찾고 있던 것보다 더 많은 학습이라면, 당신은 비유한 JSON 파서를 자유롭게 사용해야합니다.

다른 팁

균형 잡힌 괄호는 말 그대로 정규식으로 처리 할 수없는 언어의 교과서 예입니다.

bla bla bla ... 이것을 확인하십시오 :

arrayParser = "(?<Key>[\w]+)":"?(?<Value>([\s\w\d\.\\\-/:_]+(,[,\s\w\d\.\\\-/:_]+)?)+)"?

이것은 나를 위해 작동합니다

빈 값과 일치하려면 마지막 '+'로 변경됩니다.

.NET 3.5를 사용하고 있습니까? 그렇다면 사용할 수 있습니다 DataContractJsonSerializer 이것을 구문 분석합니다. 이것을 직접 할 이유가 없습니다.

.NET 3.5를 사용하지 않는 경우 사용할 수 있습니다. 제이 록.

public Dictionary<string, string> ParseJSON(string s)
{
    Regex r = new Regex("\"(?<Key>[\\w]*)\":\"?(?<Value>([\\s\\w\\d\\.\\\\\\-/:_\\+]+(,[,\\s\\w\\d\\.\\\\\\-/:_\\+]*)?)*)\"?");
    MatchCollection mc = r.Matches(s);

    Dictionary<string, string> json = new Dictionary<string, string>();

    foreach (Match k in mc)
    {
        json.Add(k.Groups["Key"].Value, k.Groups["Value"].Value);

    }
    return json;
}

이 기능은 Lukasz 정규 표현식을 구현합니다. 나는 Incride + Char to Value Group에만 추가합니다 (라이브 Connect Auth Token을 구문 분석하기 위해 그것을 사용하기 때문에)

JSON은 일반적으로 정규 표현식으로 구문 분석 할 수 없습니다 (JSON CAN의 매우 단순화 된 변형은 JSON이 아니라 다른 것입니다).

JSON을 올바르게 구문 분석하려면 실제 파서가 필요합니다.

어쨌든, 왜 JSON을 전혀 구문 분석하려고합니까? 당신을 위해 그것을 할 수있는 수많은 라이브러리가 있으며, 당신의 코드보다 훨씬 나은 도서관이 있습니다. 문 위에 포스가있는 단어가있는 모퉁이에 바퀴 공장이있을 때 왜 바퀴를 재발 명합니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top