我正在尝试使用结构定义来更改文件,如:
“typedef struct PET_fun1 {...}”有这样的定义:
“typedef struct {...} PET_fun1;”
str = <<END
typedef struct PET_fun1 {
char tam[1];
char tma[2];
char mta[2];
}
typedef struct PET_fun2 {
def : abc[3]
def : bac[3]
def : acb[3]
}
typedef struct PET_fun3 {
abc
}
typedef struct PET_fun4 {
...
}
END
puts str.gsub(/(typedef\s+struct\s+)(PET_\w+) ({.*})/m, '\1\3\2') # This regular expression isn't working.
成功进行字符串转换后我想要的输出如下所示:
typedef struct {
char tam[1];
char tma[2];
char mta[2];
} PET_fun1;
typedef struct {
def : abc[3]
def : bac[3]
def : acb[3]
} PET_fun2;
typedef struct {
abc
} PET_fun3;
typedef struct {
...
} PET_fun4;
答案 0 :(得分:2)
您的.*
元素是贪婪的,它从第1行的字符串中的第一个{
到第1行的字符串中的最后一个}
一直匹配最后一行。您需要使用lazy quantifier,以便正则表达式在它找到的第一个}
处停止。
您也可能希望PET_
带上它的前置空格。
你的最终正则表达式应该是这样的:
str.gsub(/(typedef\s+struct\s*)( PET_\w+)( {.*?})/m, '\1\3\2')
答案 1 :(得分:1)
这个答案允许在每个&#34; typedef块&#34;中使用嵌套大括号。我们的想法是将字符串拆分为分隔&#34; typedef块&#34;的空白行,操纵包含每个块的字符串,然后将它们连接回一个字符串,每个相邻对之间有一个空行。通过这种方式,在每个块中,我们可以贪婪地搜索右括号('}'
),从而允许嵌套括号。
<强>代码强>
R = /
(?<=typedef\sstruct) # match 'typedef struct' in a positive lookbehind
(\s+\w+) # match > 0 spaces followed by a word in capture group 1
(\s+{.+}) # match > 0 spaces, then '{', then any number of any
# character, greedily, then '}' in capture group 2
/xm # free-spacing regex definition and multiline modes
def doit(str)
str.split("\n\n").map { |s| s.sub(R, '\2\1') }.join("\n\n")
end
示例强>
str = <<END
typedef struct PET_fun1 {
char tam[1];
{ char { tma}[2];}
char mta[2];
}
typedef struct PET_fun2 {
def : abc[3]
def : bac[3]
def : acb[3]
}
typedef struct PET_fun3 {
abc
}
typedef struct PET_fun4 {
...
}
END
现在使用此字符串执行doit
。
puts doit(str)
# typedef struct {
# char tam[1];
# { char { tma}[2];}
# char mta[2];
# } PET_fun1
#
# typedef struct {
# def : abc[3]
# def : bac[3]
# def : acb[3]
# } PET_fun2
#
# typedef struct {
# abc
# } PET_fun3
#
# typedef struct {
# ...
# } PET_fun4
<强>解释强>
这三个步骤如下。
a = str.split("\n\n")
#=> [" typedef struct PET_fun1 { \n char tam[1];\n { char { tma}[2];} \n char mta[2];\n }",
# " typedef struct PET_fun2 { \n def : abc[3]\n def : bac[3]\n def : acb[3]\n }",
# " typedef struct PET_fun3 { \n abc\n }", " typedef struct PET_fun4 { \n ...\n }\n"]
接下来,
b = a.map { |s| s.sub(R, '\2\1') }
#=> [" typedef struct { \n char tam[1];\n { char { tma}[2];} \n char mta[2];\n } PET_fun1",
# " typedef struct { \n def : abc[3]\n def : bac[3]\n def : acb[3]\n } PET_fun2",
# " typedef struct { \n abc\n } PET_fun3", " typedef struct { \n ...\n } PET_fun4\n"]
最后,
b.join("\n\n")
给我们示例中返回的字符串。