🍎🍏🍐の器で文字の密度を記録する
— PerlでBOMを果実に変換し、文字の重みを分割する詩的処理例 —
はじめに
文字コードの境界を守ることは、記録の器を整えること。UTF-8やUTF-16のテキストファイルには、先頭にBOM(Byte Order Mark)が付いていることがあります。これは、文字の出自を示す小さな印。この記事では、Perlを使ってBOMを果実🍎🍏🍐に変換し、文字の密度(全角=2、半角=1)に応じてテキストを分割する処理を紹介します。
🍎 UTF-8
🍏 UTF-16 BE
🍐 UTF-16 LE
― それぞれのBOMを果実に見立てることで、文字コードの違いを視覚的・詩的に記録します。
ファイル名とパスについて
実環境に依存しないよう、以下のように汎用的なファイル名を使うと親切です:
my $filename = 'input_text.txt'; # 実環境に合わせて変更してください
🍐 BOMの定義と検出
use Encode;
my %chege_BOM = (
"\xEF\xBB\xBF" => '🍎', # UTF-8 BOM
"\xFE\xFF" => '🍏', # UTF-16 BE BOM
"\xFF\xFE" => '🍐', # UTF-16 LE BOM
);
# バイナリモードでBOM取得
open my $bin_fh, '<:raw', 'filename.txt' or die $!;
read($bin_fh, my $bom, 3);
$bom = $chege_BOM{$bom} // '';
close $bin_fh;
🍎 テキストの読み込みと分割処理
open my $txt_fh, '<:encoding(UTF-8)', 'filename.txt' or die $!;
my @line_arre = ();
my @rage_smole = ();
my $i = 0;
my $disp_bom = 1;
my $encoding = 'ascii';
while (my $line = <$txt_fh>) {
# BOMを先頭に表示(初回のみ)
if ($bom && $disp_bom && $i == 0){
$line = $bom . $line;
$i++;
}
# UTF-8判定と変換
if ($line =~ /[\x80-\xFF]/) {
$encoding = 'utf8' if Encode::is_utf8($line);
}
if ($encoding ne 'utf8') {
$line = Encode::decode('guess', $line);
}
# 全角=2, 半角=1 の密度計算と分割
my @l_arr = split //, $line;
my ($rage, $smole) = (0, 0);
my $retanted = 30;
my $tmp_line0 = '';
for my $char (@l_arr) {
if ($char =~ /[\x80-\xFF]/) {
$rage++;
} else {
$smole++;
}
$tmp_line0 .= $char;
if ($rage * 2 + $smole > $retanted && $retanted > 10){
push @line_arre, $tmp_line0 . "\n";
push @rage_smole, "$smole $rage\n";
($rage, $smole, $tmp_line0) = (0, 0, '');
}
}
# 残りの文字列を追加
push @line_arre, $tmp_line0 . "\n";
push @rage_smole, "$smole $rage\n";
}
close $txt_fh;
🍏 出力例と応用
• :密度に応じて分割された行の配列
• :各行の半角・全角カウント(例: )
この処理は、全角・半角の混在する日本語テキストを扱う際に、表示密度や改行位置を調整するのに役立ちます。BOMの可視化は、ファイルの由来やエンコーディングの記録にも使えます。
🍐 おわりに
このスクリプトは、文字コードの境界を丁寧に扱いながら、密度に応じた分割を行う器のような存在です。🍎🍏🍐の果実は、BOMの種類を記録する小さな詩的メタファー。にゃんにゃんさんのように、記録と共鳴を大切にする方にぴったりの処理です。
注意
最初の🍎を消したいときは、エデェッターでBOMなしにすること。
補足
🧵 出力例の補足(「出力例と応用」セクション)
# 例:@line_arre の中身
print for @line_arre;
# 例:@rage_smole の中身
print for @rage_smole;
# 出力例:
# 12 8
# 15 5
・フォントサイズ(size):たとえば 16px のフォントなら、1文字が16ピクセルの幅を持つと仮定できる。
・画面サイズ(width):たとえば 800px の表示領域があるなら、800 ÷ 16 = 50文字の半角文字が並べられる。
・この計算により、1行に収まる文字数を事前に予測できるから、密度に応じた分割処理(全角2、半角1の重みづけ)と組み合わせることで、視認性や改行位置の調整が可能になる。