3

我有一些我为 HDF5 文件格式制作的文档,它是用 GraphViz 点语言编写的。(这是一种带有很多花括号的类 C 语言。)这个主文件包含许多这样的元素:

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

我想根据 clustername 提取这个文本块。(我想单独创建这些子图的图,而不是包含所有内容的超大图。每个子图簇都是一个单独的 HDF5 文件,通过 HDF5 外部软链接连接。)

应该有一种方法可以提取这种所需的文本块(在某些特定文本模式之后匹配第一个 { 并在多行嵌套的结束 } 的练习。这似乎应该是一个相对常见的任务,因为它很普遍C 和类 C 语言。

在我看来,实现这一目标的最佳候选工具是:

awk

Python

gvpr - 随 graphviz 提供的图形流编辑器(但这对其他人没有帮助,比如 C 程序员有同样的问题,而且网络上几乎没有例子,而且语法很混乱)

sed

目前我维护主文件,然后使用 Mx ediff-regions-linewise 更新 Emacs 中的每个派生文件,但我需要一个自动化的(所以我可以使用 Make 来构建文档文件)和生成派生文件的强大方法。我使用过的唯一上述工具是sed,但由于模式很复杂并且跨越多行,我认为像 awk 或 python 这样的工具可能更适合这项任务。

事实上,我尝试了一种类似于 awk 中的引用计数的技术,但我在理解 awk 的一些更微妙的行为时遇到了问题,并且过去只真正使用过 awk 单行。

非常感谢您提供的任何帮助。-Z

4

3 回答 3

1

我不能告诉你这是最好或最优雅的解决方案,但我之前使用过这个 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]
于 2011-03-31T11:50:41.677 回答
1

使用 Perl,您将使用Text::Balanced模块。它可以在平衡分隔符之前、内部和之后返回文本。

于 2011-03-30T21:07:44.643 回答
0

您可以使用 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 {
                          }
                              ...
                              }
于 2011-03-31T00:06:32.890 回答