Perlで文字数の計算
[上に]
[前に]
[次に]
Weasel
2000/03/03(金) 12:58:43
昨日はお世話になりました。
../200003/00030036.htm
さて、新たな質問があります。
メール送信フォームの改造版を作っていまして、
一つの項目にコメントがあります。
コメントの文字数を制限したくて、このラウンジを
検索したら、
../199809/98090087.htm
に、
全角の文字数:$n = $comment =~ tr/\xa1-\xfe/\xa1-\xfe/;
$n = $n / 2;
半角の文字数:$m = $comment =~ tr/\x00-\x7f/\x00-\x7f/;
合計: $count = $n + $m;
と考えられそうな説明がありました。
これって動くのでしょうか?
また、ほかによい方法があれば教えてください。
# 正規表現を使っていること以外、よくわからないので、
# あまりコピーペーストでスクリプトを作りたくないのです。(^ ^;
S-pore
[HomePage]
2000/03/03(金) 18:43:54
漢字コードはEUCですよね?
> 全角の文字数:$n = $comment =~ tr/\xa1-\xfe/\xa1-\xfe/;
EUCの1バイト目は, 8E, 90〜9F, A1〜FE じゃありませんでしたっけ?
私のこの記憶が確かなら,↑のでは数えこぼしがでてくるような・・・。
ていうか,単純に
$str =~ s/[\x80-\xFF][\x80-\xFF]/k/g;
$len = length($str);
とかいう大ざっぱな判定で十分なような気が。(^^;
# 私は普段EUC使わないので何か間違ってたら誰か教えてください。
> また、ほかによい方法があれば教えてください。
私だったら全角は2文字分と見なしますが。(を)
S-pore
[HomePage]
2000/03/03(金) 20:10:46
> EUCの1バイト目は, 8E, 90〜9F, A1〜FE じゃありませんでしたっけ?
> 私のこの記憶が確かなら,↑のでは数えこぼしがでてくるような・・・。
すみません。これは思い違いのようです。この部分は無視してください。
Weasel
2000/03/04(土) 18:52:58
すいません。レスが遅くなりました。
> $str =~ s/[\x80-\xFF][\x80-\xFF]/k/g;
> $len = length($str);
でやってみたいと思います。
> 漢字コードはEUCですよね?
いや、JISでやろうと考えています。
オオカミ
2000/03/04(土) 19:13:31
>いや、JISでやろうと考えています。
perlのCGIの中ではJISは使えませんよ!!
EUCが一番安全
SJISはメタ文字のハンドリングが必要
Weasel
2000/03/05(日) 00:56:46
> perlのCGIの中ではJISは使えませんよ!!
えっ、初めて聞きました!
jcode.plでjisに変換する機能があったので、
てっきり大丈夫かと、、、
メール送信はJISで行いたいのです。
この場合ってフォームから取り込んで、ECUに
加工して、文字数をカウントしてからJISに
変換するって流れになるのでしょうか?
saka
2000/03/05(日) 01:02:08
Perlの中でもS-JISの処理は行なえます。
但し 単純にマッチ処理だけで扱う事は不可能に近いと言えます。
簡単に漢字を扱うならEUCにした方が良いです。
S-JISの文字数カウントは、
$line = $comment;
# LFは切り捨て(処理に問題でるから)
$line = s/\n//;
while($line ne "") {
if ($line =~ /^[\x81-\x9F\xE0-\xEF]/)
{ $n++; } # 2byte文字数
else
{ $m++; } # 1byte文字数
# 先頭の文字を削除する
$line =~ s/^[\x81-\x9F\xE0-\xEF]//;
$line =~ s/^.//;
}
$count = $n + m;
こんな感じですかね。
$lineの先頭の1文字づつSJISの漢字コードか調べて
カウントしていきます。
カウント後先頭の1文字を削除して次を調べています。
saka
2000/03/05(日) 01:04:42
漢字コードはJISでしたか..
もっと面倒な処理しないといけないですね。
直ぐには作れない。
saka
2000/03/05(日) 01:39:34
JISだとこんな感じかな動作は未確認
$line = $comment;
while($line ne "") {
if ($line =~ /(.)\x1B\$[\@B]/) {
$m += length($1);
$line =~ s/(.)\x1B\$[\@B]//;
if ($line =~ /(.)\x1B\([BJ]/) {
$n += length($1) / 2;
$line =~ s/(.)\x1B\([BJ]//;
}
else { } #エラーした時の処理(未実装)
}
else {
$m += length($line);
last;
}
}
$count = $n + m;
>この場合ってフォームから取り込んで、ECUに
>加工して、文字数をカウントしてからJISに
>変換するって流れになるのでしょうか?
それがいいです。
送信直前までEUCで処理して送信直前でJISコードに変換した方が簡単です。
Ichi
2000/03/05(日) 07:14:15
そもそも文字数を制限する目的とはなんなのでしょうか。
巨大なメールの送信を拒否するためなら、文字数でなく
単にバイト数を数えればいいと思いますが。
B-Cus
2000/03/05(日) 08:05:57
> perlのCGIの中ではJISは使えませんよ!!
> EUCが一番安全
> SJISはメタ文字のハンドリングが必要
「JIS エンコーディングをスクリプト中に書く」
と
「JIS エンコーディングをデータとして扱う」
の区別がわかってますか? この場合はどれを使ってもかまわんでしょう。
> 文字数でなく単にバイト数を数えればいいと思いますが。
賛成。
あと、このスレッドで出てきた文字数を数えるサンプル
コードは、文字コード的にもコーディングスタイル的にも
ちょっとひどいと思います。
正しい文字コードについては
http://hp.vector.co.jp/authors/VA001240/article/charcode.html
perl で日本語を美しく扱う方法については
http://www.din.or.jp/~ohzaki/perl.htm
が参考になるでしょう。
saka
2000/03/05(日) 23:27:18
>あと、このスレッドで出てきた文字数を数えるサンプル
>コードは、文字コード的にもコーディングスタイル的にも
>ちょっとひどいと思います。
済みません。ヘボなコードを書きまして。
実用上パイト数を数える方法で良いと思います。
Perl上でEUC以外の文字コードをどう処理したら考えていたので書き込みました。
Weasel
2000/03/06(月) 16:35:39
> 実用上パイト数を数える方法で良いと思います。
私も今回これでいこうと思います。ということは
$count = length($hoge);
でよろしいのでしょうか?
Ichi
2000/03/07(火) 05:12:59
それで大丈夫です。
[上に]
[前に]
[次に]