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";};