過去の桐井戸端BBS (桐ver.9)
20647 全角文字、半角英数字、半角カナが混在したデータから文字種ごとに文字数を求めたい NTA 2003/06/03-15:21
ひょっとしたらすごく些細な事かも知れないのですが、
すごく久しぶりに桐を使うので、簡単な命令文も忘れてしまっています。
マニュアルを見ようと、担当の人間に確認したところ、
(会社内で共同使用しているので)
マニュアルが何処に行ったか分からないと言われ、困っております。
どなたかお答え頂ければ幸いです。

1つの項目に、全角文字・半角英数字・半角カナが混在したデータが、
何万件という単位であるのですが、これを漢字がいくつ、半角英数字がいくつ、
という風にそれぞれの文字種ごとに抽出し、それぞれの合計を出したいのです。


例:
青yerrowあか123モモ

全角文字:3
半角英数字:9
半角カナ:2

という風に結果を表示

宜しくお願い致します。
20652 Re:文字種ごとの合計の出し方 磯田 2003/06/03-18:48
記事番号20647へのコメント
文字列は「最大何文字」という風な決まりはありますか?
それによって解決の方法が変わってくるような気がしますが。
20653 Re:文字種ごとの合計の出し方 宮城 2003/06/03-19:26
記事番号20647へのコメント
NTAさん、こんにちは。

一括処理組むしかないんじゃないでしょうか。

とりあえず、1レコードに調べたい「項目」が1件だと仮定して・・・。
[全角文字][半角英数字][半角カナ]の3項目(文字列)と[全角文字数]
[半角英数字文字数][半角カナ文字数]の3項目(数値)追加。
項目計算式に#文字数関数をセット。

当該項目を1文字ずつ末尾まで「IS関数」で調べます。
#IS全角、#ISカナの組み合わせで3ケース分けられますね。
[全角文字][半角英数字][半角カナ]のいずれかにつないでいきます。

全文字、全レコード済んだら、各文字数を集計。単純な力技ですが。

>青yerrowあか123モモ

最後の「モモ」って実は半角で掲示板が勝手に全角変換したんですね。(^^;;

>ひょっとしたらすごく些細な事かも知れないのですが、

ところで、なんのためにこういうことをやりたいかを説明していただくと、
ひょっとしたらすごく些細な解決案があるかもしれません。

20655 Re:文字種ごとの合計の出し方 うにん 2003/06/03-20:23
記事番号20647へのコメント
>全角文字:3
>半角英数字:9
>半角カナ:2
>
>という風に結果を表示

力技だと、調べたい文字を#文字置換()で""に置換すれば数えられます。
例えば英数字なら、
#文字置換(#文字置換(...#文字置換([文字列],"0",""),"1","")...)
とやると英数字を除いた文字列になるので、#文字数([文字列])-#文字数([置換後])で求まります。

20660 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-00:24
記事番号20647へのコメント
>例:
>青yerrowあか123モモ
>
>全角文字:3
>半角英数字:9
>半角カナ:2

強引技か? このデータ項目を[DATA] それれの値を求める項目を新たに作り

[全角文字数]   #文字数([DATA])-[半角英数字数]-[半角カナ数]
[半角英数字数]  #桁数(#かな(#全角([DATA])))-#桁数(#半角(#かな(#全角([DATA]))))
[半角カナ文字数] #桁数(#半角(#かな(#全角([DATA]))))-#桁数([DATA])

項目計算式に入れておいてもいいし・・・・。

データに全角や半角の空白はあるのかな?
20661 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-00:31
記事番号20660へのコメント
>>青yerrowあか123モモ

>>全角文字:3
>>半角英数字:9
>>半角カナ:2

それぞれの文字を抽出して・・・・とは要求しませんよね。

20662 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-09:38
記事番号20660へのコメント
半角数字だけの文字数を調べたければ、
#文字数(#文字列(#数値([DATA])))で求められる?

半角数字の最初の文字が「0」だったら、だめか・・・・。(ーー;)

20665 Re:文字種ごとの合計の出し方 うにん 2003/06/04-10:41
記事番号20660へのコメント
>[半角カナ文字数] #桁数(#半角(#かな(#全角([DATA]))))-#桁数([DATA])

これ、濁点があるとうまくいかないんですよね...

20667 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-10:49
記事番号20665へのコメント
>これ、濁点があるとうまくいかないんですよね...

そっか。

カ" (半角カタカナ カ+” )って、
2文字扱いにするのかな。 やっぱり1文字にするのかな?

半角カナ扱いなら、2文字で処理する?

単純に最初から「”」を「#U」にしておけば?

ポ も同じか・・・・。


20668 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-10:51
記事番号20667へのコメント
>ポ も同じか・・・・。

ポ(半角ホ+゜)がこの掲示板ではご親切に「ポ」に変換してくれている。

ポ = ホ + ゜ です。

20671 Re:文字種ごとの合計の出し方 NTA 2003/06/04-12:41
記事番号20647へのコメント
みなさん、たくさんのご回答をありがとうございます。

磯田さん>
固定長のレコードなので、1件の文字列は1850バイトと定まっています。

宮城さん>
仰って頂いたやり方に挑戦してみようと思っています。

TBLの項目属性変更で、

項目名A:データ
項目名B:全角文字(データ型:文字列)
項目名C:半角英数字(データ型:文字列)
項目名D:半角カナ(データ型:文字列)
項目名E:全角文字数(データ型:数値)
項目名F:半角英数字文字数(データ型:数値)
項目名G:半角カナ文字数(データ型:数値)

として、

項目名Eの項目計算式:#文字数([全角文字])
項目名Fの項目計算式:半文字数([半角英数字])
項目名Gの項目計算式:半文字数([半角カナ])

とする、というやり方で合っていますか?

#IS関数ですが、(str,sw)となっている「sw」には何を入れれば良いのでしょうか?
一括処理、昔からあまり使用したことがないのでよく使い方が分からないのですが…。

「モモ」は半角で入力したつもりだったんですが…全角に変換されていますね、気付かずにすみませんでした。
それから、「なんのために」という事ですが、取引先に要求されているというお答えで良いでしょうか?
通常でしたら、この処理は独自のシステムで自動的に算出できているのですが、
システムの不具合でシステム用データが使えなくなり、今回だけ手作業?でやらなければならなくなりました。
かなり独特な取り込み方をしていますので、一度使えなくなると、
元のデータが存在していてもシステム用データには二度と反映されないのです。
厄介です。

うにんさん>
仰って頂いているやり方は、ひょっとすると、数字は1〜9、英字はA〜Zまで、
半角カナはア〜ンまで地道に入れていくのでしょうか?

通りすがり(常駐モード)さん>
データには全角・半角それぞれ空白が存在してます。
文字そのものを抽出する必要はないです。あくまで、文字数が知りたいだけなので。
半角数字の最初が「0」から始まることもあります。
20672 Re:文字種ごとの合計の出し方 通りすがり(常駐モード) 2003/06/04-14:35
記事番号20671へのコメント
>データには全角・半角それぞれ空白が存在してます。

空白も1文字としてカウントするの?
カウントしないなら、#Trim([],4)で。

半角カタカナの濁音等の扱いは?
ガ(カ+゛) ⇒ 2文字 or 1文字?

によって、処理方法が変わります。
私の提示した方法を改良すれば、お望みの処理が可能だと思いますが?

20673 Re:文字種ごとの合計の出し方 うにん 2003/06/04-15:23
記事番号20671へのコメント
>仰って頂いているやり方は、ひょっとすると、数字は1〜9、英字はA〜Zまで、半角カナ
>はア〜ンまで地道に入れていくのでしょうか?

そうです、それゆえ「力技」。
前半の「#文字置換(」と後半の「,"Z","")」の部分をコピーペーストでやると
それほどたいした手間ではありません。(英数字36文字分じっさいにやってみました。
英字に大小あるときは、#LC関数も使います。)
どんな文字の組み合わせでも可能(たとえば○×の中から○を数えるとか)なのが
利点ではあります。

20674 Re:文字種ごとの合計の出し方 今村 誠 2003/06/04-16:20
記事番号20673へのコメント
NTAさんうにんさんこんにちは、↓↓これを改造して
http://www.fuku3.com/~habata/kbbs/kakov8/12873.htm
文字ごとに置換した方が一番早くて良いのではないでしょうか
今回は、半角に置換でなく、未定義値に変えて全体の文字数から
半角カナ→未定義値 全体の文字数-残った文字数=半角カナの数
半角英数→未定義値 全体の文字数-残った文字数=半角英数の数全体の文字数-半角カナ-半角英数=全角文字の数

20677 Re:文字種ごとの合計の出し方 今村 誠 2003/06/04-21:00
記事番号20674へのコメント
参考までに、英数記号の変換だけ作ってみました。

#計算(#SET(STR,#LC([元項目])),
#SET(STR,#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(&STR,
"a",""),"b",""),"c",""),"d",""),"e",""),"f",""),"g",""),"h",""),"i",""),"j",""),
"k",""),"l",""),"m",""),"n",""),"o",""),"p",""),"q",""),"r",""),"s",""),"t","")),
#SET(STR,#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(&STR,
"u",""),"v",""),"w",""),"x",""),"y",""),"z",""),"1",""),"2",""),"3",""),"4",""),
"5",""),"6",""),"7",""),"8",""),"9",""),"0",""),"!",""),"#",""),"$",""),#JIS(34),"")),
#SET(STR,#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(#S(&STR,
"%",""),"&",""),"'",""),"(",""),")",""),"-",""),"=",""),"^",""),"~",""),"\",""),
"|",""),"@",""),"`",""),"[",""),"{",""),";",""),"+",""),":",""),"*",""),"]","")),
#SET(STR,#S(#S(#S(#S(#S(#S(#S(#S(#S(&STR,",",""),"<",""),".",""),">",""),"/",""),"?",""),"_",""),"「",""),"」","")))
20678 Re:文字種ごとの合計の出し方 うにん 2003/06/04-21:08
記事番号20674へのコメント
あら(^^;
36文字やってみたと書きましたが、かっこが30重までなのは今も変わってませんね。
つまり実際は[数字なし][英字なし]の項目作って別々にやってました(^^;

今回は桐で使うのが目的のデータでもないようなので、
無理に桐でやらずhidetakeさんあたりならささっとvbsの正規表現でやってしまいそうな…

20683 Re:文字種ごとの合計の出し方 hidetake 2003/06/05-01:00
記事番号20678へのコメント
>hidetakeさんあたりならささっとvbsの正規表現でやってしまいそうな…

一応呼ばれたので作ってみました。 (^^;


テキストファイルの [半角英数字] , [半角カタカナ] ,
[全角文字] を1行毎にカウントし,別ファイルに書き出します。

書式: count.vbs x:\path\infile.txt y:\path\outfile.txt

書き出し結果:
  [全文字数],[半角英数字],[半角カタカナ],[全角]

なお,半角英数字は 半角スペースから ~ までの記号も含む
半角カタカナは 。 から ゜ の文字となっています。
そして,全角文字数は総文字数から,半角の文字数を引いた結果となっています。 (^^;

これは,何故か VBS の正規表現では [ -K] では
全角の英数字記号を含んでくれないし,中途半端に
記号の領域を含むと範囲が違うとエラーが出てしまいます。
細かく指定するといけるようですが,
実際にどれをどうカウントするかは面倒でしたので今回は手抜きです。

perl だと
半角文字:$m = $line =~ tr/[\x00-\x7f]/[\x00-\x7f]/;
全角文字:$n = $line =~
tr/[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/;
で良いのかな?


20684 Re:文字種ごとの合計の出し方 hidetake 2003/06/05-07:41
記事番号20683へのコメント
> VBS の正規表現

VBS の正規表現に関して詳しくは下記をご覧下さい。

Clinick's Clinic on Scripting:
正規表現による Visual Basic Scripting Edition (VBScript) の機能強化
http://www.microsoft.com/japan/msdn/columns/scripting/scripting051099.asp


20686 Re:文字種ごとの合計の出し方 hidetake 2003/06/05-09:27
記事番号20683へのコメント
>perl だと
>半角文字:$m = $line =~ tr/[\x00-\x7f]/[\x00-\x7f]/;
>全角文字:$n = $line =~
>tr/[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]/;
>で良いのかな?

ダメでした。
やっぱ perl は日本語環境では面倒です。 (^^;

perl もいろいろあって,最新のものは Unicode にもようやくまともに対応されマルチバイトな処理もまともになったと思いますが,
それ以前のものですとシングルバイトでの処理が基本ですのでややこしくなります。
文字コードが EUC 以外だと特にですね・・・

この処理を簡単に済ますには,日本語にも対応した
JPerl を使うのも一つですが,JPerl もいろんなところから出ていて,
これもいろいろあるようです。 (^^;

で,私の手元にあったのは次の JPerl ですが,
JPerl for Win32(perl5)
http://www.vector.co.jp/soft/dl/win95/util/se043908.html
これですと,JPerl.exe と Perl300.dll さへあれば
簡単な Perl 処理は可能であり,次のようなスクリプトで可能でした。
実行は jperl.exe count.pl infile outfile です。

count.pl
----------------------------------------------------------
#!/usr/bin/perl

if ($#ARGV ne 1) {
print "usage: count.pl infile outfile\n";
exit;
}
$sfile = $ARGV[0];
open(IN, $sfile) || die "Can't open infile: $sfile";
$dfile = $ARGV[1];
open(OUT, "> $dfile") || die "Can't open outfile: $dfile";

while($Line = <IN>){
$an = $Line =~ tr/[ -~]/[ -~]/;
$hk = $Line =~ tr/[。-゜]/[。-゜]/;
$zn = $Line =~ tr/[ -K]/[ -K]/;
$Line = $an . "," . $hk . "," . $zn . "\n";
print OUT "$Line";
}

close(IN);
close(OUT);
----------------------------------------------------------


20698 Re:文字種ごとの合計の出し方 うにん 2003/06/05-22:39
記事番号20683へのコメント
>一応呼ばれたので作ってみました。 (^^;

およびだてしてすみません。

>なお,半角英数字は 半角スペースから ~ までの記号も含む
>半角カタカナは 。 から ゜ の文字となっています。

このへんは元投稿の意図が不明確なので何ともしかたないですね。

>これは,何故か VBS の正規表現では [ -] では
>全角の英数字記号を含んでくれないし

意外にすんなりいかないようですね。UNICODEがらみでしょうかね?

桐の#IS関数を使って
繰り返し &i=1,&最大値
  置換 [文字]=#部分列([文字列],&i,1),\
     [全角文字]=[全角文字]+#IS全角([文字],1),\
     [半角英数字]=[半角英数字]+#IS半角([文字],1)*#IS英字([文字],1)+#IS半角([文字],1)*#IS数字([文字],1),\
     [半角カナ]=[半角カナ]+#IS半角([文字],1)*#ISカナ([文字],1)
繰り返し終了
こんな感じでやってみましたが、サンプルデータ500文字x500行でやってみたところ、
最初のファイルサイズが700KB位なのに、置換が終わると270MB位になります。
もう一回実行すると、途中でファイルサイズオーバーで止まってしまいます。
アンドゥ無効に設定しないと、アンドゥバッファが保存されてしまうようです?

#ISだと桐の分類に縛られるので、#文字位置を使うとこんな風。(全角文字は無理ですが。
#桁数の方がいい?)
変数 文字列{&文字群[2]={"1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,/\<>?_-=^~!""#$%&'()","アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲ0゜ァィゥェォャュョッー"}}
変数 数値{&i},日時{&開始}
置換 [数字数]=0,[英字数]=0,[カナ数]=0
*文字列の最大長を求める。固定長なら不用(代りに代入文)
項目集計 [文字列]
&開始=#日時値
繰り返し &i=1,&最大値
  置換 [英数字]=[英数字]+(#文字位置(&文字群[1],#部分列([文字列],&i,1))>0),\
     [カナ]=[カナ]+(#文字位置(&文字群[2],#部分列([文字列],&i,1))>0),\
     [全角]=[全角]+#IS全角(#部分列([文字列],&i,1),1)
繰り返し終了
確認 #文字列(#日時値-&開始)


20831 Re:文字種ごとの合計の出し方 宮城 2003/06/12-17:34
記事番号20671へのコメント
NTAさん、いまさらですが・・・。(^^;;

>#IS関数ですが、(str,sw)となっている「sw」には何を入れれば良いのでし
>ょうか?

マニュアルがなくても、「ヘルプ」か「入力」→「関数」に最低限の説明はありますからね。それから、pdfにも。

一括処理ですが、ちょっと時間があったもので、こんな風。表は別途開いておく前提です。

変数宣言 固有,文字列{&target¥
           ,&全¥
           ,&半英¥
           ,&半カ¥
           ,&wk¥
           }
ジャンプ 行番号=先頭
繰り返し(.not #終端行)
  代入 &target=[target]¥
    ,&全=""¥
    ,&半英=""¥
    ,&半カ=""
  繰り返し(&target<>"")
   &wk=#部分列(&target,1,1)
   &target=#部分列(&target,2)
   ケース開始
    ケース(#IS全角(&wk,1))
       &全=&全+&wk
    ケース その他
     ケース開始
      ケース(#ISカナ(&wk,1))
       &半カ=&半カ+&wk
      ケース その他
       &半英=&半英+&wk
     ケース終了
   ケース終了
   行訂正 [全角文字]=&全¥
      ,[半角英数字]=&半英¥
      ,[半角カナ]=&半カ
  繰り返し終了
 ジャンプ 行番号=次行
繰り返し終了

半角スペースは英数字扱い、濁点・半濁点はカナ扱いになってるようです。

戻る