在类C语言中,帮助提取匹配花括号之间的文本块

3

我有一些关于HDF5文件格式的文档,使用了GraphViz dot语言编写。(这是一种类似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
目前我通过使用M-x ediff-regions-linewise在Emacs中维护主文件,然后更新每个派生文件,但我需要一种自动化且强大的生成派生文件的方法,以便可以使用Make构建文档文件。我对上述工具唯一有一点经验的是sed,但由于模式复杂且跨越多行,我认为awk或python这样的工具更适合执行此任务。
事实上,我尝试了一种类似于awk中引用计数的技术,但我遇到了一些问题,不理解awk的某些更微妙的行为,而且过去我只使用过awk的一行代码。
非常感谢您提前提供任何帮助。 -Z

一个类似的正则表达式问题已经在这里提出 [http://stackoverflow.com/questions/1430355/regular-expression-for-content-within-braces],所以正则表达式取决于您的正则表达式引擎,并不是微不足道的问题,不会是我的首选。 - stema
1
你的“很多东西”是否包括应该被忽略的(不重要的)花括号的字符串字面量或注释? - ridgerunner
是的,返回仅翻译后的文本。 - zbeekman
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]

谢谢Dan。我会仔细查看这个,确保我理解了一切,然后尝试一下。结合Python的正则表达式模块,我认为我应该能够让它工作。 - zbeekman

1
使用Perl,你可以使用Text::Balanced模块。它可以返回平衡分隔符之前、之中和之后的文本。

谢谢更新。我会在Google上搜索一下,但请注意,我完全没有Perl经验。如果有人有更好的开箱即用解决方案,我肯定会感激不尽。与此同时,我会探索这个方案。 - zbeekman

0

您可以使用awk或任何具有良好字符串处理能力的编程语言。例如,使用一些突出的模式拆分文本。例如,假设“subgraph”分隔每个块,并且您想获取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 {
                          }
                              ...
                              }

问题在于每个子图之间都有其他我不想要的东西(连接每个子图组件的边缘)。如果只是获取线路模式1和线路模式2之间的文本,可以轻松执行以下操作:sed -n '/pattern1/,/pattern2/p' filename.dot。找到块的结尾的唯一方法是找到关闭块的匹配}。 - zbeekman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接