帮助在类似c语言的匹配花括号之间提取文本块

时间:2011-03-30 20:25:07

标签: regex graphviz text-extraction

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

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

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

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

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

AWK

gvpr - 图形流编辑器随graphviz一起提供(但这对其他人没有帮助,比如说C程序员有相同的问题,网上存在的例子很少,语法也很混乱)< / p>

SED

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

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

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

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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]

答案 2 :(得分: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 {
                          }
                              ...
                              }