Perlで文字列操作を学ぶための自作ドリル(日本語仮名変換)

こちらは日本語文字列(ひらがな/カタカナ)を扱う処理。

問題

ひらがな→カタカナ(キー入力→画面出力)

実行結果

$ perl kana_h2k.pl
あいうえお カキクケコ(改行)
アイウエオ カキクケコ
さシすセそ タちツてト(改行)
サシスセソ タチツテト
(Crtl+Dで終了)$
カタカナ→ひらがな(キー入力→画面出力)

実行結果

$ perl kana_k2h.pl
あいうえお カキクケコ(改行)
あいうえお かきくけこ
さシすセそ タちツてト(改行)
さしすせそ たちつてと
(Crtl+Dで終了)$
ひらがな⇔カタカナ(キー入力→画面出力)

実行結果

$ perl kana_swap.pl
あいうえお カキクケコ(改行)
アイウエオ かきくけこ
さシすセそ タちツてト(改行)
サしスせソ たチつテと
(Crtl+Dで終了)$
ひらがな⇔カタカナ(ファイル入出力&コード自動判別)

実行結果

$ perl kana_swap_textconv.pl kana_src.txt kana_res.txt

変換元ファイル(kana_src.txt) (文字コードはUTF8,CP932,EUC-JPを用意)

あいうえお アイウエオ
カキクケコ かきくけこ
さしすせそ サシスセソ
タチツテト たちつてと
なにぬねの ナニヌネノ
ハヒフヘホ はひふへほ
まミむメも マみムめモ
ヤ ゆ ヨ や ユ よ
らリるレろ ラりルれロ
ワ を ン わ ヲ ん
ぁぃぅぇぉ ァィゥェォ
ッャュョ  っゃゅょ 
がぎぐげご ガギグゲゴ
ザジズゼゾ ざじずぜぞ
だぢづでど ダヂヅデド
バビブベボ ばびぶべぼ
ぱぴぷぺぽ パピプペポ

変換結果ファイル(kana_res.txt) (文字コードは変換元ファイルと同じ)

アイウエオ あいうえお
かきくけこ カキクケコ
サシスセソ さしすせそ
たちつてと タチツテト
ナニヌネノ なにぬねの
はひふへほ ハヒフヘホ
マみムめモ まミむメも
や ユ よ ヤ ゆ ヨ
ラりルれロ らリるレろ
わ ヲ ん ワ を ン
ァィゥェォ ぁぃぅぇぉ
っゃゅょ  ッャュョ 
ガギグゲゴ がぎぐげご
ざじずぜぞ ザジズゼゾ
ダヂヅデド だぢづでど
ばびぶべぼ バビブベボ
パピプペポ ぱぴぷぺぽ

解答例

ひらがな→カタカナ(キー入力→画面出力)
use strict;
use warnings;
use utf8;
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
while (my $line = <STDIN>) {
  $line =~ tr/ぁ-ん/ァ-ン/;
  print $line;
}
カタカナ→ひらがな(キー入力→画面出力)
use strict;
use warnings;
use utf8;
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
while (my $line = <STDIN>) {
  $line =~ tr/ァ-ン/ぁ-ん/;
  print $line;
}
ひらがな⇔カタカナ(キー入力→画面出力)
use strict;
use warnings;
use utf8;
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
while (my $line = <STDIN>) {
  $line =~ tr/ぁ-ん,ァ-ン/ァ-ン,ぁ-ん/;
  print $line;
}
ひらがな⇔カタカナ(ファイル入出力&コード自動判別)
use strict;
use warnings;
use utf8;
use Encode;
use Encode::Guess qw/utf8 cp932 euc-jp/; # 扱うコードはUTF8, CP932, EUC-JPとする。
binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
if (@ARGV < 2) { print STDERR "ERROR: 引数が足りません(2個必要です。)\n"; exit; }
my $finame = $ARGV[0]; # 読み込みファイル
my $foname = $ARGV[1]; # 書き出し先ファイル
unless (-e $finame) { print STDERR "ERROR: 読み込みファイルが存在しません。\n"; exit; }
if (-e $foname) { print STDERR "ERROR: 書き出し先のファイルが既にあります。\n"; exit; }
open my $fi, '<', $finame or die;
binmode $fi;
my @text = <$fi>;
close $fi;
# 読み込みテキストからコードを自動判別
my $enc = guess_encoding(join ('', @text));
if (ref($enc) eq '') {
  my @names = split / or /, $enc;
  if (@names > 0) {
    $enc = find_encoding($names[0]);
  } else {
    $enc = find_encoding('ascii');
  }
}
open my $fo, '>', $foname or die;
binmode $fo;
foreach my $line (@text) {
  $line = $enc->decode($line);
  $line =~ tr/ぁ-ん,ァ-ン/ァ-ン,ぁ-ん/;
  $line = $enc->encode($line);
  print $fo $line;
}
close $fo;
exit;

追記

日本語の「ゔ」が、スーパーpre記法のソースコード内で化けてしまい使えないので、代わりに「ん」と「ン」を使う。(実際のプログラムでは「ゔ」と「ヴ」を使っても動作する。)