Помогите извлечь блок текста между соответствующими фигурными скобками на языке c-like - PullRequest
3 голосов
/ 31 марта 2011

У меня есть документация для формата файлов HDF5, написанная на языке точек GraphViz.(Это C-подобный язык с множеством фигурных скобок.) Этот мастер-файл содержит множество таких элементов:

subgraph cluster_clustername { 
                              ...
                              lots of stuff including more curly braces spanning multiple lines
                              ...
                              }

, которые я хочу извлечь из этого блока текста на основе имени кластера.(Я хотел бы создавать графики этих подграфов отдельно, а не сверхбольшие графы, содержащие все. Каждый кластер подграфа представляет собой отдельный файл HDF5, который связан через внешние программные ссылки HDF5.)

Должен быть способ извлечьэтот желаемый кусок текста (упражнение по сопоставлению первого {после некоторого определенного шаблона текста и закрытия} по нескольким строкам с вложенностью. Похоже, что это должно быть относительно распространенной задачей из-за распространенности C и C-подобных языков.

На мой взгляд, наиболее подходящими инструментами для достижения этой цели являются:

awk

python

gvpr - редактор потоков графиков, предоставляемый с Graphviz (но это не поможет другим, скажем, программисты на C с таким же вопросом, и в Интернете существует несколько примеров, а синтаксис сбивает с толку)

sed

В настоящее время я поддерживаю основной файл, затем обновляю каждый из производных файлов в Emacsиспользуя Mx ediff-region-linewise, но мне нужен автоматизированный (чтобы я мог использовать Make для создания файлов документации) и надежный метод генерации производных файлов.Единственный вышеописанный инструмент, с которым у меня есть скромный опыт, это sed , но поскольку шаблон сложен и занимает несколько строк, я думаю, что такой инструмент, как awk или python, может лучше подойти для этой задачи.

На самом деле я попробовал метод, похожий на подсчет ссылок в awk, но у меня возникли проблемы с пониманием некоторых более тонких способов поведения awk, и в прошлом я действительно использовал только вкладки awk one.

Заранее большое спасибоза любую помощь у вас есть.-Z

Ответы [ 3 ]

1 голос
/ 31 марта 2011

Не могу сказать, что это лучшее или самое элегантное решение, но я уже использовал эту функцию python, и она работает. Он не будет обрабатывать несбалансированные скобки в комментариях или строковых литералах, но обрабатывает вложенные скобки. Используйте как token = get_token_between_chars(string_to_parse, '{', '}')

def get_token_between_chars(string, start_char, end_char):
  token = ''

  n_left = 0
  n_right = 0
  closed = False

  start_index = 0
  end_index = 0
  count = 0

  for c in string:
    if c == start_char:
      n_left += 1
      if n_left == 1:
        start_index = count
    elif c == end_char:
      n_right += 1

    if n_left > n_right and not closed:
      token += c
    elif n_left > 0 and n_left == n_right:
      closed = True
      end_index = count
      break

    count += 1

  token = token[1 : len(token)]
  return [start_index, token, end_index+1]
1 голос
/ 31 марта 2011

Используя Perl, вы будете использовать Text::Balanced модуль . Он может вернуть вам текст до, внутри и после сбалансированных разделителей.

0 голосов
/ 31 марта 2011

Вы можете использовать awk или любой другой язык программирования с хорошими возможностями обработки строк. Например, разделить текст, используя какой-то видный образец. Например, скажем, что «подграф» отделяет каждый блок, и вы хотите получить cluster_A, вы можете сделать это

$ cat file
subgraph cluster_A {
                              ...
                              lots of stuff more curly {
                          }
                              ...
                              }

subgraph cluster_B {
                              ...
                              lots of stuff including more curly braces spanning multiple lines
                              ...
                              }

$ awk 'BEGIN{RS="subgraph"} /cluster_A/{ print "subgraph "$0} ' file
subgraph  cluster_A {
                              ...
                              lots of stuff more curly {
                          }
                              ...
                              }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...