First, if you are going to share files, you should use File :: Slurp . Then you can do:
my $contents = read_file $file;
read_file will be compressed on error.
Secondly, [^ typename] does not exclude only the string 'typename', but also any string containing any of these characters. Other than that, it’s not obvious to me that the template you use will consistently match the things you want to match, but I cannot comment on it right now.
Finally, to get all the matches in the file one by one, use the g modifier in the loop:
my $source = '3 5 7'; while ( $source =~ /([0-9])/g ) { print "$1\n"; }
Now that I have the opportunity to take a look at your template, I'm still not sure what to do with [^ typename], but here is an example program that captures the part between angle brackets (as it seems to be the only thing that you capture above):
use strict; use warnings; use File::Slurp; my $pattern = qr{ ^ \w+ <\s*((?:\w+(?:,\s*)?)+)\s*> \s* \w+\s*; }mx; my $source = read_file \*DATA; while ( $source =~ /$pattern/g ) { my $match = $1; $match =~ s/\s+/ /g; print "$match\n"; } __DATA__ CMyClass<int> myClassInstance; CMyClass2< int, int > myClass2Instacen; C:\Temp> t.pl int int, int
Now I suspect you would prefer the following:
my $pattern = qr{ ^ ( \w+ <\s*(?:\w+(?:,\s*)?)+\s*> \s* \w+ ) \s*; }mx;
which gives:
C:\Temp> t.pl CMyClass<int> myClassInstance CMyClass2< int, int > myClass2Instacen