use strict; use warnings; my %data; my @reverse; while () { chomp; my ($prefix, $suffix) = /^([A-Z0-9]+?)(\d+|.)$/; if (exists $data{$prefix}) { my $mapFunc = $suffix =~ /[A-Z]/ ? sub {ord $_[0]} : sub {$_[0]}; for (@{$data{$prefix}}) { next if abs ($mapFunc->($suffix) - $mapFunc->($_)) != 1; print "$prefix$_;$prefix$suffix\n"; push @reverse, "$prefix$suffix;$prefix$_\n"; } } push @{$data{$prefix}}, $suffix; } print @reverse; __DATA__ AAA30 BBC5 SHT12H DAL33B BBC49 AAA31 DAL33A BBC6 SHT12G BBC50