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

Regex 在类c语言中,帮助在匹配的大括号之间提取文本块,regex,graphviz,text-extraction,Regex,Graphviz,Text Extraction,我有一些HDF5文件格式的文档,是用GraphViz点语言编写的。(这是一种类似C的语言,有很多大括号。)此主文件包含许多类似以下内容的元素: subgraph cluster_clustername { ... lots of stuff including more curly braces spanning multiple lines

我有一些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附带的graph stream editor(但这对其他人没有帮助,比如说C程序员也有同样的问题,网络上几乎没有示例,语法也很混乱)

sed

目前,我维护主文件,然后使用M-x ediff区域逐行更新Emacs中的每个派生文件,但我需要一个自动化的(因此我可以使用Make来构建文档文件)生成派生文件的健壮方法。我对上述工具仅有的一点经验是sed,但由于模式复杂且跨越多行,我认为像awk或python这样的工具可能更适合这项任务

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

非常感谢您的帮助。
-Z

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

您可以使用awk或任何具有良好字符串处理功能的编程语言。例如,使用一些突出的模式拆分文本。例如说“子图”分离每个块,如果您想要得到集群,可以这样做

$ 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 {
                          }
                              ...
                              }

我不能告诉你这是最好或最优雅的解决方案,但我以前使用过这个python函数,它可以工作。它不会处理注释或字符串文本中不平衡的括号,但会处理嵌套的括号。使用像
token=get\u token\u-between\u-chars(string\u-to\u-parse,{',}')


对于regex解决方案,有人问了一个类似的问题,因此regex取决于您的regex引擎,而不是琐碎的,这不是我的第一选择。您的“大量内容”是否包括字符串文本或包含(非重要)的注释应该忽略的大括号?是的,这包括字符串文字和注释,用于更新。我会搜索一下,但要警告的是,我完全没有perl经验。如果有人有更多的OTS解决方案,我当然会很感激。同时,我会探索这一点。问题是,在每个子图之间,我还需要其他东西不需要(边将每个子图的不同组件连接在一起)。如果这仅仅是一个获取行模式1和行模式2之间的文本的问题,我们可以很容易地做到:
sed-n'/pattern1/,/pattern2/p'filename.dot
找到块的ed的唯一方法是找到关闭块的匹配}。谢谢Dan。我会看看这个,以确保我理解所有内容,然后试一试。与python正则表达式模块一起,我认为我应该能够实现这一点。
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]