2012-12-01 3 views
6

필자는 Pyparsing을 처음 접했고 (Python을 처음 접했을 때도). 나는 내 문제를 무엇이 잘못되었는지 설명 할 수있는 가장 간단한 형식으로 줄이려고 노력했다. (Pyparsing이 전혀 필요하지 않은 지점까지!)토큰을 수정하는 초보자 용 setParseAction 대체

문자와 숫자로 구성된 문자열이 있다고 가정 해 보겠습니다. 예 : "b7 z4 a2 de c3". 항상 편지가 있지만 번호는 선택 사항입니다. 이것을 개별 요소로 파싱 한 다음 처리해야하지만 번호가없는 맨손없는 문자가있는 경우 변경 후 "기본"번호 1을 갖도록 변경하는 것이 좋습니다. 그런 다음 모든 요소를 ​​일관된 방식으로 처리 할 수있었습니다.

from pyparsing import * 
teststring = "a2 b5 c9 d e z" 
expected_letter = Word("ABCDEFGabcdefgzZxy", exact=1) 
expected_number = Word(nums) 
letter_and_number = expected_letter + expected_number 
bare_letter = expected_letter 
bare_letter.setParseAction(lambda s,l,t: t.append("1")) 
elements = letter_and_number | bare_letter 
line = OneOrMore(elements) 
print line.parseString(teststring) 

는 불행하게도, t.append는() 나는 "1"의 목록에 추가이었다, 기대하고있는 무슨을하지 않는 다음과 같이 나는, 나는 setparseAction이 할 수 있다고 생각 파싱 ​​된 토큰. 대신 오류가 발생합니다. TypeError : 'str'개체를 호출 할 수 없습니다.

나는 정말로 두꺼운 사람일지도 모르지만, 전문가 중 한 명은 나를 똑바로 세워줄 수 있습니다.

감사

스티브 대한 파싱에 대해 얻을 수있는 기본 개념의

답변

4

하나는 문자열 단지 목록 작동하지 않는다는 것입니다,하지만 ParseResults 객체로 파싱 조각을 조립한다. ParseResults는 목록으로 액세스 할 수있는 pyparsing에 정의 된 풍부한 데이터 형식이거나 정의 된 결과 이름이있는 ParserElement에서 구문 분석 된 토큰이있는 경우 dict 또는 개체로 사용할 수 있습니다.

그러나 ParseResults는 쉽게 액세스 할 수 있도록 설계되었지만 업데이트 할 수있는 방법은 제한적입니다. 내부적으로 pyparsing에서 일치하는 각 표현식은 작은 ParseResults 객체를 생성합니다. 이것이 큰 표현식의 일부라면, 그 표현식은 + = 연산자를 사용하여 조각을 큰 ParseResults로 누적합니다.

t += ParseResults("1") 

불행하게도,이 람다으로 작동하지 않습니다 : 귀하의 경우

, 당신은 "1"을 포함하고 t에 추가 작은 ParseResults를 작성하여 전달하는 ParseResults에 추가 할 수 있습니다 - 시도해 볼 수 있습니다

lambda s,l,t: t.__iadd__(ParseResults("1")) 

그러나 이것은 조금 영리하다고 느낍니다.

Optional 클래스를 이용하려면 파서를 조금 더 재고해야 할 수도 있습니다. 꼬리말을 옵션 요소로 생각하십시오.이 요소는 요소가 누락 된 경우 제공 할 기본값을 정의 할 수 있습니다. 등

(일반적으로, 검색 문장 반환,

>>> letter = Word(alphas,exact=1) 
>>> digit = Word(nums,exact=1) 
>>> teststring= "a2 b5 c9 d e z" 
>>> letter_and_digit = Combine(letter + Optional(digit, default="1")) 
>>> print (sum(letter_and_digit.searchString(teststring))) 
['a2', 'b5', 'c9', 'd1', 'e1', 'z1'] 

그렇지 않으면 각 일치 ['a','2'], ['b','5']과 같을 것이다, 문자열에 별도의 문자와 숫자에 복귀하는 데 사용됩니다 겸용 : 난 그냥 당신이 원하는 것을 정의 할 수 있습니다 생각 단일 요소 목록처럼 보이는 ParseResults 객체의 목록 searchString의 결과를 sum에 전달하면 모든 문자열이 하나의 ParseResults에 추가됩니다.

+0

아, 이제 완벽하게 이해할 수 있습니다! 구문 분석 결과를 인쇄 할 때 일반 목록처럼 보였으므로 일반적인 방법으로 추가 할 수 있다고 생각했습니다. 또한 Optional에서 기본 설정을 허용한다는 사실을 놓쳤습니다.이 기본 설정은 더 깔끔한 전체 솔루션을 제공합니다.그리고 그것은 내 실제 프로그램에 적용될 것인데,이 프로그램은 제거 된 버전보다 조금 복잡합니다. 당신의 도움에 대한 많은 감사 .... 그리고 Pyparsing 자체! 스티브. –