The following code should do what you want, provided that the tags always start at the same letter (from the beginning or end - see the DATA section for what I mean by that).
Instead of just creating the simple pairs you might be able to shift the player names characterwise against each other. Then you might get to a solution that doesn't contain the above stated restriction.
use strict;
use warnings;
use List::Util qw/reduce/;
sub _extract {
my @names = @_;
my @pairs;
# create all xor'd pairs
for(my $i=0; $i<@names; $i++) {
for (my $j=$i+1; $j<@names; $j++) {
push @pairs, $names[$i] ^ $names[$j];
}
}
no warnings 'once';
my $or = reduce { $a | $b } @pairs;
if ( $or =~ /\0+/ ) {
my $index = $-[0];
my $length = $+[0] - $-[0];
return substr $names[0], $index, $length;
} else { # match not successful, so return undef
return;
}
}
sub extract_tag {
my @names = @_;
my $tag;
$tag = _extract(@names);
# try matching with reversed @names
# this finds common substrs at the end
$tag = reverse _extract(map {scalar reverse $_} @names)
unless defined $tag;
return $tag;
}
my @names;
local $, = ':';
local $\ = "\n";
while (<DATA>) {
chomp;
print(extract_tag(@names)), @names = (), next unless /\S/;
push @names, $_;
}
print extract_tag(@names);
__DATA__
jP|Azrael
jP|Blade
jP|Henry
Jeff.ocr
pr!me.ocr
Lokren.ocr
woRUTtan
hiRUTfango
biRUTff
salTAGo
blasTAGi
RipTAGu
-- Hofmator |