2010-05-31 6 views
6

나는이 같은 문자열을 가지고 : 나는 확실히 아직 확보하지 못했더라도이 그것에 대해가는 나의 방법은,PyParsing : setParseAction()을 올바르게 사용하고 있습니까?

[("MSE", 2110), ("MSE", 3030), ("MSE", 4102)] 

입니다 :

"MSE 2110, 3030, 4102" 

내가 출력을 원하는

def makeCourseList(str, location, tokens): 
    print "before: %s" % tokens 

    for index, course_number in enumerate(tokens[1:]): 
     tokens[index + 1] = (tokens[0][0], course_number) 

    print "after: %s" % tokens 

course = Group(DEPT_CODE + COURSE_NUMBER) # .setResultsName("Course") 

course_data = (course + ZeroOrMore(Suppress(',') + COURSE_NUMBER)).setParseAction(makeCourseList) 

이 출력 :

>>> course.parseString("CS 2110") 
([(['CS', 2110], {})], {}) 
>>> course_data.parseString("CS 2110, 4301, 2123, 1110") 
before: [['CS', 2110], 4301, 2123, 1110] 
after: [['CS', 2110], ('CS', 4301), ('CS', 2123), ('CS', 1110)] 
([(['CS', 2110], {}), ('CS', 4301), ('CS', 2123), ('CS', 1110)], {}) 

올바른 방법인가요, 아니면 완전히 해제할까요?

또한 출력이 정확하지 않습니다. course_data은 같은 형식의 course 기호 목록을 내보내려고합니다. 지금은 첫 번째 코스가 다른 코스와 다릅니다. (다른 사람이하지 않는 반면, 그것은는 {} 있습니다.)

+4

답변을 수락해야한다고 생각합니다. – Donovan

답변

5

이 그것을 할 수있는 올바른 방법인가, 또는 나는 완전히 떨어져입니까?

물론 다른 사람이 (이 바인딩 된 메서드 구문 분석 작업과 같은 예를 들어, 사용 있기는하지만 그것은 한 가지 방법은,이다 - 그래서 인스턴스는 방법은 상태를 유지할 수 있습니다 속한 - 1 부서 코드와 서로에 대한 하나를 코스 번호).

parseString 호출의 반환 값은 사용자의 의지에 따라 구부리기가 더 어렵습니다. (충분히 어두운 암흑이 그것을 할 것이라고 확신하지만 나는 Paul McGuire가 어떻게 설명 하는지를 기대합니다 .-) 그래서, 에서와 같은 방법 경로 ... :

from pyparsing import * 

DEPT_CODE = Regex(r'[A-Z]{2,}').setResultsName("DeptCode") 
COURSE_NUMBER = Regex(r'[0-9]{4}').setResultsName("CourseNumber") 

class MyParse(object): 
    def __init__(self): 
     self.result = None 

    def makeCourseList(self, str, location, tokens): 
     print "before: %s" % tokens 

     dept = tokens[0][0] 
     newtokens = [(dept, tokens[0][1])] 
     newtokens.extend((dept, tok) for tok in tokens[1:]) 

     print "after: %s" % newtokens 
     self.result = newtokens 

course = Group(DEPT_CODE + COURSE_NUMBER).setResultsName("Course") 

inst = MyParse() 
course_data = (course + ZeroOrMore(Suppress(',') + COURSE_NUMBER) 
    ).setParseAction(inst.makeCourseList) 
ignore = course_data.parseString("CS 2110, 4301, 2123, 1110") 
print inst.result 

이 방출 : 내가 올바르게 사양을 읽으면 당신이 무엇을 필요로 할 것으로 보인다

before: [['CS', '2110'], '4301', '2123', '1110'] 
after: [('CS', '2110'), ('CS', '4301'), ('CS', '2123'), ('CS', '1110')] 
[('CS', '2110'), ('CS', '4301'), ('CS', '2123'), ('CS', '1110')] 

.

16

이 솔루션은 구문 분석 될 때 부서를 외우고 번호가 발견되면 (부서, 코스튬) 터플을 내 보냅니다.

from pyparsing import Suppress,Word,ZeroOrMore,alphas,nums,delimitedList 

data = '''\ 
MSE 2110, 3030, 4102 
CSE 1000, 2000, 3000 
''' 

def memorize(t): 
    memorize.dept = t[0] 

def token(t): 
    return (memorize.dept,int(t[0])) 

course = Suppress(Word(alphas).setParseAction(memorize)) 
number = Word(nums).setParseAction(token) 
line = course + delimitedList(number) 
lines = ZeroOrMore(line) 

print lines.parseString(data) 

출력 :

[('MSE', 2110), ('MSE', 3030), ('MSE', 4102), ('CSE', 1000), ('CSE', 2000), ('CSE', 3000)] 
0

물론, everbody는 대한 파싱을 사랑한다. 이 분할 같은 쉬운 물건 sooo를 훨씬 쉽게 grok 수하는 것입니다

data = '''\ 
MSE 2110, 3030, 4102 
CSE 1000, 2000, 3000''' 

all = [] 
for row in data.split('\n'): 
     klass,num_l = row.split(' ',1) 
     all.extend((klass,int(num)) for num in num_l.split(',')) 
0
data = '''\ 
MSE 2110, 3030, 4102 
CSE 1000, 2000, 3000''' 

def get_courses(data): 
    for row in data.splitlines(): 
     department, *numbers = row.replace(",", "").split() 
     for number in numbers: 
      yield department, number 

이 과정 코드에 대한 발전기를 줄 것이다. 필요한 경우 list()으로 목록을 만들거나 직접 반복 할 수 있습니다.

관련 문제