初めて質問します。
文字コードを判別するにはどうしたらよいのでしょうか?
よろしくお願いします。
テキスト内の上のほうにある"日本語"で、文字コードを判断するのが一般的なようです。
詳しくはとほほのWWW入門の、アラカルトのページに
ブラウザの文字コード判断のしくみが載っていたと思いますが、
DelphianWorldに、そういう文字コード判断モジュールがあったような気もします。
まずそっちを探してみてはどうでしょうか?
BIG5やGB、EUC-KRなどの判定方法はわかりません。
僕も知りたいです。
以下はSJIS,JIS,EUCの場合です。
SJISの場合、
c1 := 2バイト文字の第1バイト;
c2 := 2バイト文字の第2バイト;
isknj1 := ((c1>=$81) and (c1<=$9F))||((c1>=$ED) and (c1<=$FC)); //第1バイトチェック
isknj2 := ((c2>=$40) and (c2<=$FC) and (c2<>$7F)); //第2バイトチェック
で、isknj1 and isknj2のとき、SJISの2バイト文字です。このほかにASCII文字の判別が必要です(要は半角文字の判別です)。
JIS
これは面倒です。これがわかるとEUCもわかります。
JISは、エスケープ文字(ESC=文字コード$1B)により文字の種類が変わります。
最初はASCIIとして処理されますが、たとえば
ESC + '$' + '@'
もしくは
ESC + '$' + 'B'
の時、次の文字から2バイト文字です。
ESC + '(' + 'H'
もしくは
ESC + '(' + 'J'
のとき、次の文字からASCII文字です
ASCIIのときは、$20-$7Eまでの文字をそのまま使います。
2バイト文字では、次のような操作が必要です。
c1 := 2バイト文字の第1バイト;
c2 := 2バイト文字の第2バイト;
if (c1 and 1)=1 then
begin
if c2 < $60 then c2 := c2 + $1F else c2 := c2 + $20;
end
else
begin
if c1 < $5F then c1 = (c1 + $E1) shr 1 else c1 = (c1 + $161) shr 1;
end;
EUCは、JISの2バイト文字に当たる部分の、各バイトの最上位ビットが立っています。このため、ESCによる文字の種類分けが必要ありません。
たとえば、
ABCあいうDEF
は、
JIS: 41 42 43 1B 24 42 24 22 24 24 24 26 1B 28 42 44 45 46
EUC: 41 42 43 A4 A2 A4 A4 A4 A6 44 45 46
となり、ESC+'$B' (1B 24 42)や、ESC+'(B' (1B 28 42)の分だけEUCの方が短くなります。
SJISとEUCは、区別することができません。
EUCの「あいう」は、EUCでは
"、「、、、ヲ"
の半角カタカナに当たります。
判別の順序としては、
ASCII, JIS, SJIS/EUCで、SJISとEUCはどちらを優先するかによって、決定するほかありません。
# 内容によっては、SJISのみ、EUCのみに判定されることもありますが、その場合は期待通りの判別になります
たかみちえさん、にしえさん、ありがとうございます。
やっぱり難しいですね・・・
たかみちえさんのモジュールはよくわかりませんでしたが、jconvertの判別機能で自分は十分だったのでそれを試用することにしました。
DLLもあるようですが。
本当にありがとうございました。
すいません。
よこからの便上質問で、大変申し訳ないのですが、
にしのさん>
>SJISの場合、
>c1 := 2バイト文字の第1バイト;
>c2 := 2バイト文字の第2バイト;
>isknj1 := ((c1>=$81) and (c1<=$9F))||((c1>=$ED) and (c1<=$FC)); //第1バイトチェック
>isknj2 := ((c2>=$40) and (c2<=$FC) and (c2<>$7F)); //第2バイトチェック
>で、isknj1 and isknj2のとき、SJISの2バイト文字です。このほかにASCII文字の判別が必要です(要は半角文字の判別です)。
の部分の
> このほかにASCII文字の判別が必要です(要は半角文字の判別です)。
なんですが、この半角文字の判別というのは、具体的に何の為に行うものなんでしょうか?
isknj1 and isknj2のとき、SJIS の 2 バイト文字であることが
わかっただけでは、その読み込んだテキストは SJIS と断定できないということ
なんでしょうか?
横からの質問すいません。よろしくお願いいたします。
たとえば、
ABCあいう
というテキストがあったとき、半角文字を処理しなければ、
isknj1 and isknj2 はfalseになるのでSJISとして処理されませんよね。
最初のABCを処理するとき、とりあえず保留するための処理が必要になります。
にしのさん、どうもありがとうございます。
> 最初のABCを処理するとき、とりあえず保留するための処理が必要になります。
ということは、例えば、あるテキストファイルが Shift_JIS で
あるかどうかを「チェックするだけ」であるなら、
isknj1 and isknj2 が true であるなら、そのテキストファイルは Shift_JIS と
判断しても OK ということなんでしょうか?
上記の 2 バイト文字の 1 バイト目を見つけるには、Bytetype を
使用すれば、判断できると考えているのですが…。
つまり、
「ABCあいう」という文字列あった場合、Bytetype で 2 バイト文字の 1 バイト目("あ"の 1 バイト目)を見つけて(つまり、mbLeadByte が返されたか
どうかをチェックして)、にしのさんが示していました
>c1 := 2バイト文字の第1バイト;
>c2 := 2バイト文字の第2バイト;
>isknj1 := ((c1>=$81) and (c1<=$9F))||((c1>=$ED) and (c1<=$FC)); //第1バイトチェック
>isknj2 := ((c2>=$40) and (c2<=$FC) and (c2<>$7F)); //第2バイトチェック
>で、isknj1 and isknj2のとき、SJISの2バイト文字です。このほかにASCII文字の判別が必要です(要は半角文字の判別です)。
を行い、isknj1 and isknj2 が true であったら、Shift_JIS である。
と考えているのですが、正しいでしょうか?
よろしくお願いいたします。とんちんかんな質問でしたら、すいません。
EUCよりSJISのほうが優先であればそれで問題ありません。
問題なのは、「EUCの2バイトコードで、SJISの2バイトコード(もしくは半角カタカナ2文字)にあたるコードがある」ことです。
もし、JIS,SJIS,EUCを同時に判別するのであれば、whileなどでループさせて、状態を「JIS/SJIS/EUCの可能性あり」とし、
・ASCIIコードであれば、可能性は保留(変化なし)
・ESCコードがあればSJIS,EUCの可能性はない(JISの可能性のみ)
・SJISコードであれば、JISの可能性はない
・EUCコードであれば、JISの可能性はない
・可能性が1つであれば、その文字コードと断定
と処理すればよいかと思います。
SJISとEUCの処理では、さらに、
・SJISであり、確実にEUCでなければJIS/EUCの可能性はない(SJISの可能性のみ)
・EUCであり、確実にSJISでなければSJIS/JISの可能性はない(EUCの可能性のみ)
とできます。
# 条件はわすれましたが、いくつかのコードがあったと思います
よく読んでいませんでした。
> ということは、例えば、あるテキストファイルが Shift_JIS で
> あるかどうかを「チェックするだけ」であるなら、
そういうことです。
その場合、EUCのテキストは半角カタカナの「SJISのテキスト」ですので、SJISと判別される可能性もありますが。
間違い。
> その場合、EUCのテキストは半角カタカナの「SJISのテキスト」ですので、SJISと判別される可能性もありますが。
その場合、EUCのテキストは半角カタカナの「SJISのテキスト」となる場合もあるので、その場合はSJISと誤認しますが。
にしのさん、どうもありがとうございます。
> その場合、EUCのテキストは半角カタカナの「SJISのテキスト」となる場合も
> あるので、その場合はSJISと誤認しますが。
厳密に判定するとなると、かなり大変な作業になるのですね。
とても勉強になりました。どうもありがとうございました。
ツイート | ![]() |