use strict; use warnings; my @structs; local $/ = '};'; while (my $struct = ) { my ($name, $data) = $struct =~ m/\bstruct\s+(\w+).+\bint\s*:\s*(\d+)\s*;/s; my @strings = $struct =~ m/(?<={|;)\s*pointer:\s*"([^"]*)";/sg; next if ! defined $data || ! @strings; push @structs, {name => $name, data => $data, strings => \@strings}; } for my $struct (@structs) { print <{name} { int: $struct->{data}; STRUCT print " pointer: $_;\n" for @{$struct->{strings}}; print "};\n\n" } __DATA__ struct first { pointer: "hello world"; pointer: "the end is nigh"; pointer: "this is the end"; int: 23; }; struct second { pointer: "Gidday"; int: 12; pointer: "the second struct is nigh"; pointer: "in fact this is it"; }; struct third {int: 21; pointer: "When two is not enough, you need a third";}; #### struct first { int: 23; pointer: hello world; pointer: the end is nigh; pointer: this is the end; }; struct second { int: 12; pointer: Gidday; pointer: the second struct is nigh; pointer: in fact this is it; }; struct third { int: 21; pointer: When two is not enough, you need a third; };