I think the point that you are perhaps missing is that split really uses a regular expression as pattern for splitting the input, not simply a character, whether printable or not. Just to illustrate this point:
$ perl -e '$s="foobaaarbaz"; print join " ", split /ba+r/, $s;'
foo baz
As you can see, this code was able to determine that "baaar" matches the pattern /ba+r/ and split the string on it. And, BTW, this gives you much more expressive power once you realize that. In the example you gave, the problem comes from the fact that you use a string in your $sep variable, and that sting contains characters which are special in regexes. This string is then converted to a regex and gets messed up. You don't have the problem if you define $sep as a regular expression instead of a string:
$ perl -e '$s="85|mat\@com";$sep=qr/\|/;($key,$email)=split($sep,$s);
+print "$key\t$email\n";'
85 mat@com
Defining the $sep variable as a regex, using $sep=qr/\|/, suffices to solve the issue.
To see how your string is transformed into a regex and compare to the real regex, consider this session under the Perl debugger:
DB<1> $s = "\|"
DB<2> $t = qr/$s/
DB<3> p $t
(?^:|)
DB<4> $u = qr/\|/
DB<5> p $u
(?^:\|)
As you can see, your $sep variable is transformed into a simple alternation (the $t variable), it is no longer the escaped | ('\|') that you need (the $u variable). A simple alternation ('|') pattern will split the string into individual characters, and your code was retrieving the first two elements of the list output by split, i.e. the first two characters of your string.
|