0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🍎🍏🍐 PerlでBOMを明示的に読み込み、UTF-8テキストを丁寧に分割する方法2

Posted at

🍎🍏🍐の器で文字の密度を記録する

— 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の重みづけ)と組み合わせることで、視認性や改行位置の調整が可能になる。

以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?