Во-первых, если вы собираетесь использовать файлы, вы должны использовать File :: Slurp . Тогда вы можете сделать:
my $contents = read_file $file;
read_file выскочит при ошибке.
Во-вторых, [^ typename] не исключает только строку «typename», но также и любую строку, содержащую любой из этих символов. Кроме того, для меня не очевидно, что используемый вами шаблон будет последовательно соответствовать вещам, которые вы хотите, чтобы он соответствовал, но я не могу сейчас это прокомментировать.
Наконец, чтобы получить все совпадения в файле один за другим, используйте модификатор g в цикле:
my $source = '3 5 7';
while ( $source =~ /([0-9])/g ) {
print "$1\n";
}
Теперь, когда у меня была возможность взглянуть на ваш шаблон, я все еще не уверен, что делать с [^ typename], но вот пример программы, которая фиксирует часть между угловыми скобками (как это кажется быть единственной вещью, которую вы захватываете выше):
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
Теперь, я подозреваю, вы бы предпочли следующее:
my $pattern = qr{
^
(
\w+
<\s*(?:\w+(?:,\s*)?)+\s*>
\s*
\w+
)
\s*;
}mx;
, что дает:
C:\Temp> t.pl
CMyClass<int> myClassInstance
CMyClass2< int, int > myClass2Instacen