На самом деле у вас есть ряд ошибок в этом фрагменте, и вы можете пересмотреть некоторые документы по pyparsing, чтобы убедиться, что у вас есть основы.
Word(stringOfChars)
будет соответствовать группе символов, которые все существуют в данном stringOfChars
. Word(alphanums)
будет соответствовать «ABC», «slkjfljlsdflsdjf», «2330098324», «392084lsfd0238» и так далее. Таким образом, Word("{")
будет соответствовать не только "{", но также "{{" и "{{{{{{{{{"}} — в некоторых из этих мест, где вы определяете знаки препинания, я думаю, вы, скорее всего, имеете в виду использование Literal
, не Word
. Literal
будет соответствовать только точной строке, используемой в его конструкторе, без неявного повторения.
Word(string1, string2)
будет соответствовать группе символов, начинающихся с одного из символов в string1
, за которым сразу следует ноль или более символов в string2
. В вашем определении controlCodes
, я думаю, вы хотите принять только начальный символ «\», за которым следует 1 или более alphanums
, «*» или «;». Правильнее было бы написать как Word('\\', alphanums+'*'+';')
Поскольку вы анализируете RTF, который часто включает символы '\', вы добьетесь большего прогресса, если будете использовать необработанные строковые литералы Python, что позволит вам вводить строки, содержащие обратную косую черту, без необходимости удваивать их. Сравнивать
print document.parseString('{\\*\\falt Times New Roman}')
и
print document.parseString(r'{\*\falt Times New Roman}')
Единственная загвоздка в том, что вам все равно придется удваивать обратную косую черту, если это последний (или единственный) символ в строке.
Проблема, с которой вы сталкиваетесь, заключается в том, что ваше определение header
потребляет слишком много входных данных. Попробуйте добавить эти строки после определения header
:
header.setName("header")
header.setDebug()
Это будет распечатывать диагностические сообщения каждый раз, когда в синтаксическом анализаторе будет достигнуто header
, и показывать, был ли синтаксический анализ успешным или нет. Если синтаксический анализ прошел успешно, он также покажет, что было сопоставлено. Вот что вы получите при разборе вашего примера текста:
Match header at loc 1(1,2)
Matched header -> ['\\', '*', '\\falt', 'Times', 'New', 'Roman']
Traceback (most recent call last):
File "rtf.py", line 26, in <module>
print document.parseString(r'{\*\falt Times New Roman}')
File "c:\python26\lib\site-packages\pyparsing.py", line 1041, in parseString
raise exc
pyparsing.ParseException: Expected "}" (at char 1), (line:1, col:2)
Я не думаю, что вы ожидали, что header
прочитает "Times New Roman" до конца.
Если вы еще не успели начертить БНФ для своего синтаксического анализатора, я настоятельно рекомендую вам сделать это. После того, как вы это запишете, попробуйте проследить БНФ через вашу тестовую строку - будьте настолько буквальны, насколько сможете, не делайте НИКАКИХ предположений о том, где OneOrMore
выражения должны останавливаться, потому что "это очевидно". Pyparsing не выполняет никаких действий, о которых вы не говорите.
person
PaulMcG
schedule
16.11.2013