Python, анализирующий древовидные данные

#python #parsing

#python #синтаксический анализ

Вопрос:

У меня есть информация о символе из шрифта, который выглядит следующим образом:

 (CHARACTER C T
   (CHARWD R 0.6944475)
   (CHARHT R 0.686111)
   (COMMENT
      (KRN C y R -0.027779)
      (KRN C e R -0.083334)
      (KRN C o R -0.083334)
      (KRN C r R -0.083334)
      (KRN C a R -0.083334)
      (KRN C A R -0.083334)
      (KRN C u R -0.083334)
      )
   )
  

Есть ли простой способ проанализировать это в python? Я уже использовал BeautifulSoup раньше, но для этого требуется вложенная <tag> </tag> подобная информация. Было бы нетрудно преобразовать это в XML и обратно, но, похоже, это было бы изобретением колеса. Как мне перенести эту информацию в объект данных, которым я могу манипулировать и снова выплевывать обратно?

Комментарии:

1. Синтаксический анализ такой структуры в принципе не сложен (на самом деле, похоже, что это должно быть довольно легко, если вы знаете, что означают поля и что они могут содержать). Но если вам нужны все интересные функции API дерева элементов, вам лучше всего преобразовать его в XML. Или, что менее круто, но все же нормально, создайте из него DOM. Если вам не нужен никакой навороченный API, вы также можете просто разобрать его в свои собственные структуры данных, созданные вручную.

2. у @delnan есть это, просто проанализируйте его в свою собственную структуру данных. Если вы не хотите попытаться взаимодействовать с другой библиотекой или подобной библиотекой, для которой требуются данные в определенной форме, синтаксический анализ в вашей собственной структуре данных, вероятно, самый простой. Если вы действительно хотите использовать стандартный стиль, попробуйте json.

3. @brc: Ну, если планируется много программных манипуляций с такими данными, и преобразовать их в XML легко, я бы предпочел это лично. lxml упрощает работу с XML, что может перевесить накладные расходы на преобразование (накладные расходы для программистов, а не для производительности).

4. Быстрый взлом состоял бы в том, чтобы немного изменить его с помощью регулярных выражений, а затем прочитать его в кортеже, используя ast.literal_eval . Затем вы можете поработать с кортежем (или, скорее, с кортежем кортежей) или преобразовать его в xml, а затем поработать над ним.

Ответ №1:

Вы могли бы использовать pyparsing. Ваш пример очень похож на s-выражение, и у них есть анализатор s-выражений в разделе примеров: http://pyparsing .wikispaces.com/file/view/sexpParser.py

Комментарии:

1. Pyparsing больше не размещается на wikispaces.com . Перейдите к github.com/pyparsing/pyparsing

2. @PaulMcG, спасибо, что указали на это… Я обновил ссылку в своем ответе

Ответ №2:

Это преобразует ваши данные в структуру данных python. Не уверен, что это то, что вы ищете?

 s = """(CHARACTER C T
       (CHARWD R 0.6944475)
       (CHARHT R 0.686111)
           (COMMENT
           (KRN C y R -0.027779)
           (KRN C e R -0.083334)
           (KRN C o R -0.083334)
           (KRN C r R -0.083334)
           (KRN C a R -0.083334)
           (KRN C A R -0.083334)
           (KRN C u R -0.083334)
           )
        )"""

s = re.sub(")", "),", s)
t = re.sub('([(,s])(w )', '\1"\2",', s)
eval(t[:-1].replace('\', ''))