我有一些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
答案 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 {
}
...
}