UTF-8 の範囲外の文字かどうか調べる


UTF-8 の範囲外の文字かどうか、どうやって判別したらいいのだろう - @kyanny's blog


こんなんでどうでしょうか。


check_utf8.pl

#!/usr/local/bin/perl
use strict;
use warnings;

use Encode;

while (<>) {
    eval {
        decode_utf8($_, Encode::FB_CROAK);
    }; if ($@) {
        warn "line $.: invalid utf-8 string";
    }
}


というか、decode_utf8できるかってことだけど。

適当に

$ cat utf8.txt euc-jp.txt sjis.txt utf8.txt > mixed.txt
$ ./check_utf8.pl < mixed.txt

とかで。


追記

なんとなくUTF-8じゃない部分のエンコーディングと復元したデータを表示するようにした。

#!/usr/local/bin/perl
use strict;
use warnings;
use utf8;

use Encode;
use Encode::Detect::Detector;

binmode STDOUT => ':encoding(euc-jp)';

while (my $octets = <>) {
    eval {
        decode_utf8($octets, Encode::FB_CROAK);
    }; next unless $@;

    print "line $.: invalid utf-8 string found\n";
    my $encoding = detect($octets) || 'Windows-1252';
    my $e = find_encoding($encoding);
    if ($e) {
        print "encoding: $encoding\n";
        printf 'data: %s'. "\n", $e->decode($octets);
    } else {
        print "Unknown encoding: $encoding\n";
    }
}
$ ./check_utf8.pl < mixed.txt
line 2: invalid utf-8 string found
encoding: EUC-JP
data: こんにちわ

line 3: invalid utf-8 string found
encoding: Shift_JIS
data: こんにちわ

よしよし。