Flethuseo Flethuseo - 19 days ago 5
Ruby Question

Trying to relocate of a word using a multi-line regular expression

I'm trying to change a file with struct definitions like:

"typedef struct PET_fun1 { ... } " to have definitions like this:

"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.


The output I want after a successful string transformation would look like this:

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;

Answer

Your .* element is greedy, it's matching all the way from the very first { in the string on line 1 to the last } in the string on the last line. You need to use a lazy quantifier so that the regex stops at the first } it finds.

You also probably want PET_ to bring its preceeding space with it.

Your final regex should look something like this:

str.gsub(/(typedef\s+struct\s*)( PET_\w+)( {.*?})/m)