時々エンコードを「西ヨーロッパ言語」に変えてこのページを見てみると、Perlが日本語をどう解釈しているかがなんとなくわかるかもしれません。
なお、ここでは機種依存文字は面倒なので入れていません。
エスケープシーケンスに注意
―ソЫ噂浬欺圭構蚕十申曾箪貼能表暴予禄兔喀媾彌拿杤歃濬畚秉綵臀藹觸軆鐔饅鷭xx\\
これらの文字は、2バイト目に「\」が含まれているため、Perlの中ではその次の1バイトがエスケープシーケンスとして解釈され、文字化けしたり、エラーが起こったりします。
これを解消するには、文字を「"」の代わりに「'」で囲んだり、その文字の直後に「\」を入れてエスケープシーケンスを解除すれば良いようです。
正規表現に注意
/タЭ運蛙疑型洪賛戎真楚耽顛膿豹某与録竸喊嫂弯擔杰歐濘畤秧綽膺蘓訖躾鐃饋鷽zz^^(2バイト目に「^」が含まれる)ーゼЪ閏骸擬啓梗纂充深措端甜納票房夕麓兌喙媼彈拏杣歇濕畆禺綣膽藜觴躰鐚饉鷦ww∵[(2バイト目に「[」が含まれる)
‐ゾЬ云馨犠珪江讃従疹曽綻転脳評望余肋兢咯嫋彎拆枉歉濔畩秕緇臂蘊訃躱鐓饐鷯yy(2バイト目に「]」が含まれる)
−ポл榎掛弓芸鋼旨楯酢掃竹倒培怖翻慾處嘶斈忿掟桍毫烟痞窩縹艚蛞諫轎閖驂黥哈哄||(2バイト目に「|」が含まれる)
これらの文字は、2バイト目に特殊な文字が含まれているため、正規表現中で使うと、例えば「タンス」の場合は「 ^ンス」というわけのわからない正規表現が出来上がり、場合によってはエラーを起こします。
「\」のときのように後ろに「\」を付けてエスケープする方法が使えないので、「'タ'」を「pack("C*", 0x83) .
'\^'」に置き換えるなど、1バイト目と2バイト目を別々に表記したり、正規表現を使わない方法にしたりと工夫しなければなりません。
多少の誤差を気にしないのであればこういった文字をすべて「??」に置き換えるという荒技もありですが・・・・
もしかしたらもっといい方法があるかもしれません。
サンプル(476byte)
ちなみに、一番簡単で手っ取り早い解決方法は、シフトJISではなくEUCで書いてしまうことです。
シフトJISで表示してやる必要があれば、適当なライブラリを使って表示時に変換すればよいでしょう。