Хорошо, поэтому я задал несколько небольших вопросов об этом проекте, но я все еще не очень уверен в проектах, которые я придумаю, поэтому я собираюсь задать вопрос по более широкой теме. шкала.
Я анализирую предварительные описания для каталога курса. Описания почти всегда следуют определенной форме, что заставляет меня думать, что я могу разобрать большинство из них.
Из текста я хотел бы сгенерировать график предусловий отношений. (Эта часть будет легкой после того, как я проанализирую данные.)
Некоторые примеры входов и выходов:
"CS 2110" => ("CS", 2110) # 0
"CS 2110 and INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, 3300, 3140" => [("CS", 2110), ("CS", 3300), ("CS", 3140)] # 1
"CS 2110 or INFO 3300" => [[("CS", 2110)], [("INFO", 3300)]] # 2
"MATH 2210, 2230, 2310, or 2940" => [[("MATH", 2210), ("MATH", 2230), ("MATH", 2310)], [("MATH", 2940)]] # 3
Если все описание является просто курсом, оно выводится напрямую.
Если курсы объединены («и»), все они выводятся в одном списке
Если курс отделен ("или"), они находятся в отдельных списках
Здесь мы имеем «и» и «или».
Одна оговорка, которая облегчает: кажется, что вложение фраз "и" / "или" никогда не бывает больше, чем показано в примере 3.
Каков наилучший способ сделать это? Я начал с PLY, но не мог понять, как разрешить конфликты уменьшения / уменьшения. Преимущество PLY в том, что легко манипулировать тем, что генерирует каждое правило разбора:
def p_course(p):
'course : DEPT_CODE COURSE_NUMBER'
p[0] = (p[1], int(p[2]))
С PyParse менее понятно, как изменить вывод parseString()
. Я думал о том, чтобы развить идею @Alex Martelli по сохранению состояния в объекте и создать выходную информацию, но я не уверен, как именно это лучше всего сделать.
def addCourse(self, str, location, tokens):
self.result.append((tokens[0][0], tokens[0][1]))
def makeCourseList(self, str, location, tokens):
dept = tokens[0][0]
new_tokens = [(dept, tokens[0][1])]
new_tokens.extend((dept, tok) for tok in tokens[1:])
self.result.append(new_tokens)
Например, для обработки дел "или":
def __init__(self):
self.result = []
# ...
self.statement = (course_data + Optional(OR_CONJ + course_data)).setParseAction(self.disjunctionCourses)
def disjunctionCourses(self, str, location, tokens):
if len(tokens) == 1:
return tokens
print "disjunction tokens: %s" % tokens
Как disjunctionCourses()
узнает, какие фразы поменьше разделять? Все, что он получает, это токены, но то, что было проанализировано до сих пор, хранится в result
, так как функция может сказать, какие данные в result
соответствуют каким элементам token
? Думаю, я мог бы найти токены, а затем найти элемент result
с теми же данными, но это было бы запутанно ...
Кроме того, существует много описаний, которые включают разный текст, например:
"CS 2110 or permission of instructor"
"INFO 3140 or equivalent experience"
"PYSCH 2210 and sophomore standing"
Но это не критично, что я анализирую этот текст.
Как лучше решить эту проблему?