2014-12-13 5 views
1

이스케이프 된 따옴표를 포함하여 따옴표 안에 JSON 키 이름을 구문 분석하려고합니다. 내 생각은 다음과 같습니다 (?<!\\)\"가 화면 "하지만,하지 \"하지만 파이썬은 불균형 괄호에 대해 불평한다 \REGEX in Python : 무엇이 잘못 되었습니까? (! <! \) ". + (? <! \) "?

(?<!\\)\".+(?<!\\)\" 

로 시작 따옴표 하지 사이에 아무것도 걸릴. 나는 (?<!\\\)\" 파이썬 행복 사용하지만이 작동하지 않는 경우

re.findall('(?<!\\\)\".+(?<!\\\)\"','"this is \"the\". key"."and this.is.the.child"') 

리드 :

['"this is "the". key"."and this.is.the.child"'] 

내가 기대하는 경우 :

['"this is "the". key"', '"and this.is.the.child"'] 

분할을 동봉 점에서 "탈출하지 않고.

나는 '아무것도 필요하지는 않지만 esc가 필요하다고 느낀다. aped double quote '를 쓰지 만, [^"] 화면에 큰 따옴표가있는 경우, 문자를 리터럴로 사용하는 [] 집합 내에서 (?<!\\\)\" 표현식을 무효화하는 방법을 모르겠습니다. 나는 [^(?<!\\\)\"]과 같은 것을 원하지만 작동하지 않습니다.

내가 좋아하는 일을 시도 [^ [ "] | (\")] + (큰 따옴표, 또는 \ "아무것도하지만)하지만 그건 ... 중 하나가 작동하지 않는 것

수; t이 작업을 수행 할 수있는 올바른 방법을 찾을 수가 ... 어떤 아이디어 도움을

감사

편집 :?

내 진정한 목표는 전체 '텍스트'를 분할 할 수있을 것입니다 JSON 키 이름을 사용하여 영숫자로만 변환 에스. 이 변환은 여기서는 관계가 없지만 목표는 키를 분할하여 계층 구조를 올바르게 나타 내기위한 것입니다. 키는 텍스트 형식입니다.

편집 2 :에 표시된대로

OmnipotentEntity이 .. 대부분 좋아, 파서를 작성하는 것이 기다려야 할 것이다 경우에도이 솔루션은 아래의 "\"또는 "\\"의 경우를 지원하지 않습니다 자신의 코멘트.

나는 큰 따옴표로 묶어야되지 않은 키에 대한 Avinash 라지 에서 대답하지만, 추가 지원에 의해 영감을

"(?:\\"|[^"])*?"|(?<=\.)[^".]+?(?=\.)|^[^".]+?(?=\.)|(?<=\.)[^".]+?$ 

으로 정착 : 에는 따옴표로 끝나는 라인의 시작합니다. .key. 및 .lastkey [공백]을 같은 정규식으로 대체 할 때 발견 된 문자열 수보다 1 적은 요소를 찾거나 오류가 발생해야합니다. something like .. outside ""는 해당 테스트에 실패합니다.

+0

JSON은 LL (1) 언어이지만 일반 언어는 아닙니다. 정규식을 사용하여 혼란 스러울 수도 있지만 정규 표현식에 의존하기보다는 실제 파서를 작성하는 것이 좋습니다. 이유는 더 쉽게 추론 할 수 있고 오류를 지적하기 때문입니다. – OmnipotentEntity

답변

1

정규식을 원시 문자열 표기법으로 정의하십시오.

DEMO

또는

>>> re.findall(r'(?<!\\)".*?(?<!\\)"', s) 
['"this is \\"the\\". key"', '"and this.is.the.child"'] 
경기가 앞에 백 슬래시되지 않습니다 주장 부정적인 lookbehind라는
  • (?<!\\)

    >>> s = r'"this is \"the\". key"."and this.is.the.child"' 
    >>> re.findall(r'"(?:\\"|[^"])*?"', s) 
    ['"this is \\"the\\". key"', '"and this.is.the.child"'] 
    

    .

  • " 큰 따옴표와 일치합니다.

  • .*?(?<!\\)" 앞뒤에 백 슬래시가없는 큰 따옴표까지 모든 문자를 유치하지 않습니다.

+0

''\\ "'은 어떻습니까? 어때? ""\\\ "'? – OmnipotentEntity

+0

이 메시지가 표시되지 않습니다 .. 설명이 있다면 op에 요청하십시오. –

+0

OP는 유효한 JSON 키와 일치하는 정규 표현식을 요구했습니다. "\\"은 유효한 json 키입니다. "\\"이 (가) 정규 표현식과 일치하지 않습니다 – OmnipotentEntity

2

기본적으로 인용 부호가있는 문자열을 일치시키는 정규 표현식을 사용하는 것은 일반적으로 불가능합니다. JSON은 정규 언어가 아닙니다 (정규 언어는 모두 LL (1)이지만 모든 LL (1) 언어가 정규 언어가 아니며 JSON이이 중 하나입니다). 따라서 정규 표현식과 일치 할 수 없습니다.

Avinash Raj의 정규 표현식 (?<!\\)".*?(?<!\\)"은 사례 "\\"에서 실패합니다. 따옴표 뒤에는 \이 있지만 백 슬래시는 이스케이프로 작동하지 않습니다. 그러나 "\\\""이 실패하게되므로이 상황을 특별한 경우로 처리 할 수 ​​없습니다. 그리고이 상황을 특별한 경우 4 \, 그 다음 5 \ 등을 사용할 수 있습니다.

Lookbehind는 표준 정규 표현식의 일부가 아니므로 일반 정규 표현식보다 더 많은 문법을 사용할 수 있습니다. 따라서이 경우 작동하는 정규 표현식을 생각해 낼 수 있습니다. 그러나 대신에 파서를 작성하는 것이 좋습니다. LL (1) 문법에 대해 매우 쉽게 수행 할 수 있습니다. 이해하기 쉽고 이해하기 쉽고 부서지기 쉽고 부적합한 JSON을 다루는 데 더 많은 영향력을 줄 것이며이 경우 더 나은 진단 메시지를 작성할 수 있습니다.

+0

파서 작성 방법에 대한 예제가 있습니까? 당신은 쉽게 말할 수 있지만 어디서부터 시작해야할지 모르겠습니다. 문자를 파싱하면 그게 무슨 뜻입니까? – MrE

+0

기본적으로 그렇습니다. 문자 단위로 이동하고 파서의 상태를 유지합니다. LL (1)은 한 번에 한 글자 만 앞으로 나가면 구문 분석 할 수 있음을 의미합니다. 예제 파서를 보려면 wikipedia 페이지를 확인하십시오. https://en.wikipedia.org/wiki/LL_parser#Parser_implementation_in_Python – OmnipotentEntity

관련 문제