2016-11-24 10 views
2

CSV 파일을 구문 분석하려고하는데 Perl6의 proto regex에서 정규식 이름에 액세스하려고합니다. 그것은 Nil로 밝혀졌습니다. 적절한 방법은 무엇입니까?경기 내에서 캡처에 어떻게 액세스합니까?

grammar rsCSV { 
    regex TOP { (\s* <oneCSV> \s* \, \s*)* } 
    proto regex oneCSV {*} 
      regex oneCSV:sym<noQuote> { <-[\"]>*? } 
      regex oneCSV:sym<quoted> { \" .*? \" } # use non-greedy match 
} 

my $input = prompt("Enter csv line: "); 

my $m1 = rsCSV.parse($input); 
say "==========================="; 
say $m1; 
say "==========================="; 
say "1 " ~ $m1<oneCSV><quoted>; # this fails; it is "Nil" 
say "2 " ~ $m1[0]; 
say "3 " ~ $m1[0][2]; 

대단히 감사합니다!

lisprog

답변

3

내가

은 아마 당신이 펄 6 구문 분석을 학습하고 일부 일회용 코드를 작성에 초점을 맞추고있다 csv 파일을 구문 분석하는 것을 시도하고있다

자세한 논의를 보완 크리스토프의 대답. 그러나 산업용 강도 CSV 파싱을 원한다면 Text :: CSV 모듈 [1]에 유의하십시오.

난 당신이 펄 6 구문 분석을 학습하는 경우 명명 된 정규 표현식을

에 액세스를 시도하고, jnthn의 문법 추적 및 디버거 [2]에 유의하시기 바랍니다. Perl6의 프로토 정규식에서

문제는 프로토 정규식 인 관련이 없습니다.

대신 문제는 경기 개체가 명명 된 캡처에 해당하는 동안 는 당신이 $m1에 저장된 전체 경기 객체에 저장, 당신이 찾고있는 정확하게 어디에 저장되어 있지되고 있다는 점이다.

캡처와 일치하는 일치하는 개체는 어디에 표시됩니까?

지금 무슨 일이 일어나고 있는지 확인하기 위해 내가하려는 일을 시뮬레이션 해 보겠습니다. 하나의 캡처, 문자열 "ab"과 일치하는 "명명 된"(일명 "연관성") 캡처를 선언하는 정규식을 사용하겠습니다. 당신은 아마도이 $m1<named-capture>에서 $m1 내에 표시 할 것으로 예상 할 위치를 명명 된 캡처에 해당하는

given 'ab' 
{ 
    my $m1 = m/ $<named-capture> = (ab) /; 

    say $m1<named-capture>; 
    # 「ab」 
} 

경기 개체가 저장됩니다.

그러나 너는 $m1<oneCSV>으로 Nil을 얻고있었습니다. 뭐라 구요? 당신의 $m1<oneCSV>이 작동하지 않은 이유는

캡처 두 가지 유형이 있습니다 (일명 "연관")라는 이름 (일명 "위!") 번호가. / (...) /에서

given 'ab' 
{ 
    my $m1 = m/ ($<named-capture> = (ab)) /; # extra parens added 

    say $m1[0]<named-capture>; 
    # 「ab」 
} 

괄호가 하나의 최상위 번호 캡처를 선언 : 당신이 <oneCSV>을 포위하여 정규식에 쓴 괄호는 캡처 번호를 도입했다. 일치하는 경우 해당 일치 항목은 $m1[0]에 저장됩니다. (당신의 정규식 지금의 3 분의 1을 $m1[2]에서 다음 괄호의 두 번째 쌍을 일치 무엇에 해당하는 다른 일치하는 개체가 $m1[1]에 저장됩니다 / ... (...) ... (...) ... (...) ... /, 또 다른 모습, 그리고합니다.) $<named-capture> = (ab)의 경기 결과가 다음 저장

내부$m1[0]. 그래서 say $m1[0]<named-capture>가 작동합니다.

지금까지 그렇게 좋았습니다. 그러나이 절반 밖에 이야기 ...

코드에서 $m1[0]<oneCSV> 작동하지 않을 이유

중 하나

이다에서 $m1[0]<named-capture> 동안 코드가 작동 바로 위에, 당신은 은 여전히 ​​$m1[0]<oneCSV>에 일치하는 객체를 얻을 수 없겠죠 원래 코드. 당신이 사용하기 때문에 당신은 또한 제로 번째 캡처 일치하는 항목이 여러을 요구하기 때문이다 *quantifier 다음 * 정량 여러 일치를 요구하기 때문에

given 'ab' 
{ 
    my $m1 = m/ ($<named-capture> = (ab))* /; # * is a quantifier 

    say $m1[0][0]<named-capture>; 
    # 「ab」 
} 

, 펄 6 경기이 $m1[0]에 객체 목록을 작성 . (당신은 길이 1의 목록 결국이 경우에) 즉, 단지 $m1[0][0] (그리고 $m1[0][1], $m1[0][2] 등, 단 하나의 일치입니다.)

  • 가 둥지를 캡처

    요약;

  • * 또는 + 중 하나에 의해 정량화 캡처는 단지 하나의 중첩 수준에 해당합니다.

  • 원본 코드에서 찾고자하는 일치 개체를 얻으려면 say $m1[0][0]<oneCSV>;을 작성해야합니다.


[1] 관련 모듈을 설치하고 코드의 시작 (펄 5 플러스 XS 구현을위한) 또는 use Text::CSV:from<Perl5>; (순수 펄 6 구현) use Text::CSV; 물품. (talk slides (예 : "csv"를 클릭하면 슬라이드를 진행할 수 있습니다), video, Perl 6 module, Perl 5 XS module.)

[2] 관련 모듈을 설치하고 코드 시작 부분에 use Grammar::Tracer; 또는 use Grammar::Debugger;을 작성하십시오. ' (talk slides, video, modules.)

+1

정말 고마워, raiph !!! 나는 당신의 상세한 설명 후에 나의 문제를 지금 본다. 시간 내 주셔서 대단히 감사합니다 !!! – lisprogtor

+0

@lisprogtor 여러분을 환영합니다. 어떤 특정한 비트가 당신에게 가장 도움이되었거나/나에게 도움이되었다고 말할 수 있다면 그것은 나에게 특히 도움이 될 것입니다. :) – raiph

+1

감사합니다. raiph. 명명 된/번호 매겨진 캡처 및 일치 개체 트리와 *, perl6이 단일 개체 대신 목록을 구성한다는 사실에 대한 설명입니다. 다시 한 번 감사드립니다! – lisprogtor

2

당신이 $m1[0]를 통해 얻을 캡처 그룹의 범위 내에서 <oneCSV> 삶의 일치합니다.

그룹이 *으로 계량되면 결과가 다시 목록이됩니다. 즉, 일치 객체를 가져 오기 위해 다른 색인 작업이 필요합니다 (예 : $m1[0][0]).

명명 된 캡처는 이름으로 액세스 할 수 있습니다 (예 : $m1[0][0]<oneCSV>). 이것은 이미 protoregex의 해당 지점의 일치 결과를 포함합니다.

특정 일치 항목 대신 전체 일치 목록을 찾으려면 >> 또는 map (예 : $m1[0]>>.<oneCSV>)을 사용할 수 있습니다.

+0

Christoph. 필자의 대답으로 펄 6에 대한 나의 이해가 더 커졌습니다! – lisprogtor