Как я могу проанализировать повышенный текст для последующей обработки?

Это не возможно с маркировкой WinForms как есть. Маркировка должна иметь точно один шрифт точно с одним размером и одной поверхностью. У Вас есть несколько опций:

  1. отдельное Использование маркирует
  2. Create новый производный класс Управления, который делает его собственный рисунок через GDI + и использование это вместо Маркировки; это - вероятно, Ваш наилучший вариант, поскольку он дает Вам полный контроль над тем, как дать управлению команду форматировать свой текст
  3. Использование сторонний элемент управления "метка", который позволит Вам вставить отрывки HTML (существует набор - проверяют CodeProject); это было бы чужой реализацией № 2.
5
задан Rigsby 7 July 2009 в 07:12
поделиться

4 ответа

Редактировать : благодаря уточнению и изменению в спецификации я отредактировал свой код, все еще используя явный класс Node в качестве промежуточного шага для ясности - - логика состоит в том, чтобы превратить список строк в список узлов, затем превратить этот список узлов в дерево (с помощью соответствующего атрибута отступа), затем распечатать это дерево в удобочитаемой форме (это просто «отладка- help "шаг, чтобы проверить, что дерево хорошо построено и, конечно, может быть закомментировано в окончательной версии скрипта, который, как и конечно, будет брать строки из файла, а не жестко закодировать их для отладки! -), наконец, создайте желаемую структуру Python и распечатайте ее. Вот код, и как мы После этого мы увидим, что результат почти , как указывает OP, с одним исключением - но сначала код:

import sys

class Node(object):
  def __init__(self, title, indent):
    self.title = title
    self.indent = indent
    self.children = []
    self.notes = []
    self.parent = None
  def __repr__(self):
    return 'Node(%s, %s, %r, %s)' % (
        self.indent, self.parent, self.title, self.notes)
  def aspython(self):
    result = dict(title=self.title, children=topython(self.children))
    if self.notes:
      result['notes'] = self.notes
    return result

def print_tree(node):
  print ' ' * node.indent, node.title
  for subnode in node.children:
    print_tree(subnode)
  for note in node.notes:
    print ' ' * node.indent, 'Note:', note

def topython(nodelist):
  return [node.aspython() for node in nodelist]

def lines_to_tree(lines):
  nodes = []
  for line in lines:
    indent = len(line) - len(line.lstrip())
    marker, body = line.strip().split(None, 1)
    if marker == '*':
      nodes.append(Node(body, indent))
    elif marker == '-':
      nodes[-1].notes.append(body)
    else:
      print>>sys.stderr, "Invalid marker %r" % marker

  tree = Node('', -1)
  curr = tree
  for node in nodes:
    while node.indent <= curr.indent:
      curr = curr.parent
    node.parent = curr
    curr.children.append(node)
    curr = node

  return tree


data = """\
* 1
 * 1.1
 * 1.2
  - Note for 1.2
* 2
* 3
- Note for root
""".splitlines()

def main():
  tree = lines_to_tree(data)
  print_tree(tree)
  print
  alist = topython(tree.children)
  print alist

if __name__ == '__main__':
  main()

При запуске выдает:

 1
  1.1
  1.2
  Note: 1.2
 2
 3
 Note: 3

[{'children': [{'children': [], 'title': '1.1'}, {'notes': ['Note for 1.2'], 'children': [], 'title': '1.2'}], 'title': '1'}, {'children': [], 'title': '2'}, {'notes': ['Note for root'], 'children': [], 'title': '3'}]

Помимо порядка ключей (который является несущественны и не гарантируются в dict, конечно), это почти по запросу - за исключением того, что здесь все примечания отображаются как записи dict с ключом notes и значение, представляющее собой список строк (но запись примечаний опускается, если список был бы пуст, примерно так, как это сделано в примере в вопросе).

В текущей версии вопроса, как представлять примечания немного неясно; одна заметка отображается как отдельная строка, другие - как записи, значение которых является строкой (вместо списка строк, который я использую). Непонятно что ' Предполагается, что примечание должно отображаться как отдельная строка в одном случае и как запись в формате dict во всех остальных, поэтому эта схема, которую я использую, является более регулярной; и если примечание (если оно есть) представляет собой одну строку, а не список, будет ли это означать ошибку, если для узла появляется более одной примечания? В последнем отношении эта схема, которую я использую, является более общей (позволяет узлу иметь любое количество заметок от 0 и выше, а не только 0 или 1, как очевидно подразумевается в вопросе)

Написав так много кода ( ответ перед редактированием был примерно таким же длинным и помог уточнить и изменить спецификации), чтобы предоставить (я надеюсь) 99% желаемого решения, я надеюсь, что это удовлетворит исходный плакат, поскольку последние несколько настроек кода и / или спецификаций для ему должно быть легко сделать так, чтобы они соответствовали друг другу!

и если примечание (если оно есть) представляет собой одну строку, а не список, будет ли это означать ошибку, если для узла появляется более одной примечания? В последнем отношении эта схема, которую я использую, является более общей (позволяет узлу иметь любое количество заметок от 0 и выше, а не только 0 или 1, как очевидно подразумевается в вопросе).

Написав так много кода ( ответ перед редактированием был примерно таким же длинным и помог уточнить и изменить спецификации), чтобы предоставить (я надеюсь) 99% желаемого решения, я надеюсь, что это удовлетворит исходный плакат, поскольку последние несколько настроек кода и / или спецификаций для ему должно быть легко сделать так, чтобы они соответствовали друг другу!

и если примечание (если оно есть) представляет собой одну строку, а не список, будет ли это означать ошибку, если для узла появляется более одной примечания? В последнем отношении эта схема, которую я использую, является более общей (позволяет узлу иметь любое количество заметок от 0 и выше, а не только 0 или 1, как очевидно подразумевается в вопросе).

Написав так много кода ( ответ перед редактированием был примерно таким же длинным и помог уточнить и изменить спецификации), чтобы предоставить (я надеюсь) 99% желаемого решения, я надеюсь, что это удовлетворит исходный плакат, поскольку последние несколько настроек кода и / или спецификаций для ему должно быть легко сделать так, чтобы они соответствовали друг другу!

6
ответ дан 14 December 2019 в 04:45
поделиться

Стеки - действительно полезная структура данных при синтаксическом анализе деревьев. Вы просто всегда сохраняете путь от последнего добавленного узла до корня в стеке, чтобы вы могли найти правильного родителя по длине отступа. Что-то вроде этого должно работать для анализа вашего последнего примера:

import re
line_tokens = re.compile('( *)(\\*|-) (.*)')

def parse_tree(data):
    stack = [{'title': 'Root node', 'children': []}]
    for line in data.split("\n"):
        indent, symbol, content = line_tokens.match(line).groups()        
        while len(indent) + 1 < len(stack):
            stack.pop() # Remove everything up to current parent
        if symbol == '-':
            stack[-1].setdefault('notes', []).append(content)
        elif symbol == '*':
            node = {'title': content, 'children': []}
            stack[-1]['children'].append(node)
            stack.append(node) # Add as the current deepest node
    return stack[0]
1
ответ дан 14 December 2019 в 04:45
поделиться

Поскольку вы имеете дело со схемой, вы можете упростить задачу, используя стек. По сути, вы хотите создать стек, в котором есть dict , соответствующие глубине контура. Когда вы анализируете новую строку и глубина контура увеличивается, вы помещаете новый dict в стек, на который ссылался предыдущий dict в верхней части стека. Когда вы разбираете строку с меньшей глубиной, вы выталкиваете стек, чтобы вернуться к родителю. И когда вы встречаетесь со строкой той же глубины, вы добавляете ее к dict наверху стека.

1
ответ дан 14 December 2019 в 04:45
поделиться

Синтаксис, который вы используете, очень похож на Yaml. У него есть некоторые отличия, но его довольно легко изучить - его основное внимание уделяется тому, чтобы человек читал (и писал).

Взгляните на сайт Yaml. Там есть некоторые привязки python, документация и прочее.

0
ответ дан 14 December 2019 в 04:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: