お世話になっております。
フォームから入力された文字を、
「半角カタカナ→全角カタカナ」変換したいのですがうまくいきません。
コーディングは以下の通りですが、問題の箇所がわかりません。
どなたかご教授ください。
なお、jcode.plは、最新のものを使っています。
#↓===============================================
##### フォームデータ受け取り
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read( STDIN , $buffer , $ENV{'CONTENT_LENGTH'} );
} else {
$buffer = $ENV{'QUERY_STRING'};
}
# 文字コードを正確に取得するために,全ての送信データをいったん文字コードチェックする
$buffer1 = $buffer;
$buffer1 =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg;
$kcode = &jcode::getcode(*buffer1);
@pairs = split(/&/ , $buffer);
##### フォームデータのデコード、漢字コードをsjisに変換
foreach $pair (@pairs) {
($k,$v) = split(/=/,$pair);
$v =~ tr/+/ /;
$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
&jcode'convert(*v,"sjis",$kcode);
# 半角カナを全角に変換
if($kcode eq 'sjis') {
&jcode::h2z_sjis(\$v);
}
if($kcode eq 'euc') {
&jcode::h2z_euc(\$v);
}
if($kcode eq 'jis') {
&jcode::h2z_jis(\$v);
}
$in{$k} = $v;
}
#↑===============================================
(なお、全角スペースは、半角スペースなどに変更願います。)
よろしくお願いします。
A 回答 (8件)
- 最新から表示
- 回答順に表示
No.8
- 回答日時:
文字量が少ないと文字コードの判別が正確にできないので、既に回答があったように文字量を増やす工夫が必要だと思います。
半角カナが混じっても判別精度を上げる方法が下記サイトに記述されてます。
参考にされるといいと思います。
Perlメモ
http://www.din.or.jp/~ohzaki/perl.htm#JP_Code
jcode.plはかなり古いライブラリーで、今から新しく書くスクリプトではあまりお薦めできません。以下のような変遷をたどっています。
jcode.pl → Jcode.pm → Encode.pm
今は、Encode.pmを使って文字列をUnicode化して使うのが主流です。
ちょっと難しいかもしれませんが、チャレンジしてみてください。
Encode::Guess -- データからエンコーディングを推測する
http://www.kt.rim.or.jp/~kbk/perl-5.8/guess.html
Perl で半角カナと全角カナの変換をする
http://www.serendip.ws/archives/2185
以下、参考コードを書いてみました。
use Encode 'from_to';
use Encode::JP::H2Z;
my $v = 'アイウエオ';
print $v, ' -> ';
my $enc = getcode($v);
die '文字コードが取得できませんでした' if $enc =~ /or/;
from_to($v, $enc, 'euc-jp');
Encode::JP::H2Z::h2z(\$v);
from_to($v, 'euc-jp', $enc);
print $v;
sub getcode {
my $str = shift;
my $ascii = '[\x00-\x7F]';
my $re_sjis_c = '[\201-\237\340-\374][\100-\176\200-\374]';
my $re_sjis_kana = '[\241-\337]';
my $re_euc_c = '[\241-\376][\241-\376]';
my $re_euc_kana = '\216[\241-\337]';
my $re_euc_0212 = '\217[\241-\376][\241-\376]';
require Encode::Guess;
my $enc = Encode::Guess::guess_encoding($str, qw/euc-jp shiftjis 7bit-jis/);
return $enc->name if ref $enc;
if( $enc =~ /shiftjis/ and $enc =~ /euc-jp/ ) {
if( $str !~ /^(?:$re_euc_c|$re_euc_kana|$re_euc_0212|$ascii)*$/o ) {
if( $str =~ /^(?:$re_sjis_c|$re_sjis_kana|$ascii)*$/o ) {
return 'shiftjis';
}
}
return 'euc-jp';
}
return $enc;
}
ご回答、誠にありがとうございます。
半角カタカナを全角カタカナに変換するのが、簡単にできないとは知りませんでした。
私のような初心者には、難易度が高すぎるようです。
出直した方がよさそうです。
今回の皆様のご回答は、必ず、役立たせたいと思います。
ありがとうございました。
No.7
- 回答日時:
> 半角のアを入力した場合、$kcode= (値なし)
> 半角のアイを入力した場合、$kcode=euc
> 全角のアを入力した場合、$kcode=sjis
> 全角のアイを入力した場合、$kcode=sjis
何事もなかったかのように書いてますけど、これが問題だと思わなかったのですか?
Shift_JISで入力しているのですから、この4つ全て「sjis」になるのが、期待している結果ですよね?
それが値なしや「euc」になるってことは、判定に失敗しているってことですよね?
最初の結果は、
Shift_JIS半角カナだけの入力→$kcode='euc'と誤判定→そのままconvertでEUCからSJISへ変換→当然コード不一致で文字化け
となったものです。
後の「正しく動いた」と言ってる方も
Shift_JIS半角カナだけの入力→$kcode='euc'と誤判定→if( $kcode eq 'euc' )が成立→ h2z_sjisを実行:EUCの場合の処理のはずなのに、SJISのh2zを使っている→元がShift_JISなので、h2z_sjisが期待通りに動作→「正しく動いた」ように見える
と、けっして「正しい動作」ではありません。
実際、本当にEUCで入力があって、正しく判定されたとすると
EUCの入力→$kcode='euc'と正しく判定→if( $kcode eq 'euc' )が成立→ h2z_sjisを実行→元がEUCなのでなので、h2z_sjisでは誤動作→カタカナばかりの変な出力
となります。
> 半角カタカナ1文字が入った場合、及び、半角カタカナとそれ以外の文字が混在する場合に、正しい結果(半角カタカナ→全角カタカナ変換)が得られません
それは、正しくsjisと判定されたときに、なんの処理もしていないからです。
convertの位置がおかしい(→h2zの処理の後にconvertする)なくらいで、最初のプログラムでやりかたは大体あってます。
問題なのは、$kcodeが実際のコードと違うことがある、ということ。
特に、Shift_JISの半角カナはEUCと誤判定されやすい、ということ。
jcode.pl だけでの対策は不可能。#6さんが例示したような「正しく判定されるしくみ」を入れる必要があります。
No.6
- 回答日時:
リンクに jcode の解説がありますので、読んでみてください。半角カナに関しては、次のように書かれています。
> 文字列が半角カナを含んでいる時、文字コードが EUC であるか シフトJIS であるかの判断は非常に困難で、時には誤った結果を返すことがあります。従って、半角カナは、文字コードの自動認識の判断対象からはずされます。文字列に半角カナを含むときの時の、文字コードの自動認識は、保証されません。
文字コードの判別に失敗しているのだと思います。判別の精度を上げるために、input タグの hidden 属性を利用してダミーの文字列を使ってみてはどうでしょうか? CGI 側では捨てるだけで済みます。
<input type="hidden" name="judge" value="ここに判別用の少し長めの全角文字">
No.5
- 回答日時:
#2の補足にあった例から言えば、誤判定されてる可能性が高いです。
自動判定というは、他のコードにない文字のならびや、使われている文字の比率から予想するもので、文字数が少ないと精度が落ちます。(短くても精度が高いのは、ESC等を使うjisくらいです)
特に、Shift_JISの半角カナはEUC-JPの漢字用の文字と重なる部分が多く、Shift-JISの半角カナが数文字あるだけでは、EUC-JPと誤判定されても不思議はありません。
# 試しに、EUC-JPで書かれたテキストをShift_jisで無理矢理開いてみてください。(ブラウザで文字コードをShift_jisに変更するでもいいです)半角カナの羅列になるはずです。
だから、#2さんも
『「文字コードの判定」が正しくできていることは確実なのですか?』
とおっしゃっているのです。
$kcodeを表示するなりファイルに保存するなりして、確認はしたのですか?
この回答への補足
>$kcodeを表示するなりファイルに保存するなりして、確認はしたのですか?
半角のアを入力した場合、$kcode= (値なし)
半角のアイを入力した場合、$kcode=euc
全角のアを入力した場合、$kcode=sjis
全角のアイを入力した場合、$kcode=sjis
です。
なお、
&jcode'convert(*v,"sjis",$kcode);
をコメントアウトし、さらに
if($kcode eq 'sjis') {
&jcode::h2z_sjis(\$v);
}
if($kcode eq 'euc') {
&jcode::h2z_euc(\$v);
}
if($kcode eq 'jis') {
&jcode::h2z_jis(\$v);
}
を
if($kcode eq 'euc') {
&jcode::h2z_sjis(\$v);
}
のみにすると、半角カタカナの文字化けは解消されました。(理由は理解できていません)
ただし、文字化けは解消されたのですが、
・半角カタカナ1文字の場合、半角のまま。
・半角カタカナ2文字以上の場合、全角に変換。
・半角カタカナ1文字以上と全角カタカナの混在の場合、半角、全角それぞれそのまま。
・半角カタカナ1文字以上と漢字(又はひらがな)の混在の場合、半角カタカナは半角カタカナのまま。
・半角カタカナ1文字とブランクと半角カタカナ2文字以上の場合、全て半角のまま。
・半角カタカナ2文字以上とブランクと半角カタカナ2文字以上の場合、全て全角に変換。
という結果になりました。
つまり半角カタカナ1文字が入った場合、及び、半角カタカナとそれ以外の文字が混在する場合に、
正しい結果(半角カタカナ→全角カタカナ変換)が得られません。
引き続き、調査しておりますが、何かお分かりになられましたら、ご教授ねがいます。
よろしくお願いします。
No.3
- 回答日時:
> &jcode'convert(*v,"sjis",$kcode);
> # 半角カナを全角に変換
> if($kcode eq 'sjis') {
> &jcode::h2z_sjis(\$v);
> }
> if($kcode eq 'euc') {
> &jcode::h2z_euc(\$v);
> }
> if($kcode eq 'jis') {
> &jcode::h2z_jis(\$v);
> }
Shift_JIS に変換してから元の $kcode で半角全角の変換をするのは間違っているのでは?
&jcode'convert(*v,"sjis",$kcode);
&jcode::h2z_sjis(\$v);
ご回答ありがとうございます。
> # 半角カナを全角に変換
> if($kcode eq 'sjis') {
> &jcode::h2z_sjis(\$v);
> }
> if($kcode eq 'euc') {
> &jcode::h2z_euc(\$v);
> }
> if($kcode eq 'jis') {
> &jcode::h2z_jis(\$v);
> }
の部分を、
&jcode::h2z_sjis(\$v);
だけにしたのですが、
結果は同じ(半角カタカナの場合、文字化け)でした。
ご指摘は、こういう意味では、なかったのでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセルシート中の全角英数字を半角に変換したい 4 2022/07/07 13:14
- Access(アクセス) Accessのテキストボックスの入力文字制限 1 2023/01/18 20:43
- その他(Microsoft Office) WordやExcelで英数字のみ半角または全角にしたい 6 2022/08/03 08:18
- PHP PostgreSQLからCSV形式でエクスポートする際にカラム内の改行をとる方法 1 2023/02/22 10:05
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- Excel(エクセル) エクセルの数式で教えてください。 1 2023/02/02 10:20
- C言語・C++・C# S-JIS → JIS コード変換するには 3 2023/02/09 23:55
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) VBA 「,」・空白・カタカナ等の複数条件のマクロ 2 2023/08/23 11:57
- Excel(エクセル) EXCELでの文字・数字入力の基本について教えてください。 2 2023/05/29 23:17
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
英数字のみ全角から半角に変換
-
VBAの文字列の中に”(全角のダブ...
-
Accessで日付や数値を全角で表...
-
エクセルの検索が正しくできな...
-
Accessのテキストボックスの入...
-
小説の点々は……と繋がらなくて...
-
VBA 文字に半角が含まれて...
-
「 _ _ 」の正式名称を...
-
住宅にカナを入力する際に丁目...
-
プログラミングでは、半角括弧...
-
Accessでのグループ化で全角・...
-
[Excel VBA] ODBCによる外部デ...
-
コマンドプロンプト 全角を含ん...
-
IEからEdgeへの移行に伴うIMEの...
-
Excel VBAでオートシェイプ内の...
-
エクセルでの”々”の扱い
-
Excelの中に全角ひらがな、漢字...
-
VBScriptの正規表現で半角スペ...
-
全角文字だけ抜き出したい
-
エクセルにMicrosoft Barcode C...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
英数字のみ全角から半角に変換
-
住宅にカナを入力する際に丁目...
-
全角英数字の必要性が理解できない
-
Excel関数またはVBAでの質問に...
-
エクセルにMicrosoft Barcode C...
-
IEからEdgeへの移行に伴うIMEの...
-
VBA 文字に半角が含まれて...
-
COBOL・全角判定
-
プログラミングでは、半角括弧...
-
word差し込み印刷 半角カタカ...
-
メモ帳の段落の揃え方
-
よくアカウント等に使われる 半...
-
Accessのテキストボックスの入...
-
ダブルコーテーションの置換
-
エクセルでの”々”の扱い
-
小説の点々は……と繋がらなくて...
-
大文字と全角文字は同じ意味で...
-
[VBScript]バイト長の判定
-
封筒の宛先で縦書きの書き方
-
VBで、String型のデータが、...
おすすめ情報