use warnings; use strict; my $in_file = "DeineDatei.csv"; my $out_file = "DeineAndereDatei.csv"; my %new_lines; my $regex = qr[ \A (.+?) \t # zwischen Anfang und erstem TAB => $key (\d+) # $prefix (?: # Klammern nicht behalten \( # ( (.+?) # Inhalt zwischen Klammern => $extension \) # ) )? # nur falls vorhanden ]x; open (my $in_fh, '<', $in_file) or die "kann $in_file nicht lesen!\n"; while (my $line = <$in_fh>) { my ($key, $prefix, $extension) = $line =~ /$regex/; if (defined $extension) { my @extensions = split(/,/, $extension); ITEM: for my $item (@extensions) { # Zahlenbereich angegeben? if ($item =~ /(\d+)-(\d+)/) { if ($2 < $1) { print "fehlerhafte Bereichsangabe: '$item' in Zeile $.\n"; next ITEM; } for my $i ($1..$2) { push @{$new_lines{$key}}, "$prefix$i"; } } elsif ($item =~ /(\d+)/) { # nur Zahlen verwenden push @{$new_lines{$key}}, "$prefix$1"; } } } else { push @{$new_lines{$key}}, "$prefix"; } } close($in_fh); open (my $out_fh, '>', $out_file) or die "kann $out_file nicht schreiben!\n"; for my $key (sort {$a <=> $b} keys %new_lines) { for my $value (sort {$a <=> $b} @{$new_lines{$key}}) { print $out_fh "$key\t$value\n"; } } close($out_fh); print "fertig.\n";