半角全角判定(文字数取得機能追加)
半角全角判定 - 永字八法の焼き直し。
※2011-01-15 書きなおし。
パートA
mov %0,100 numalias is_zen_result,%0:inc %0 numalias is_zen_target,%0:inc %0 numalias is_zen_cmp,%0:inc %0 numalias is_zen_len,%0:inc %0 numalias letter_result,%0:inc %0 numalias letter_base,%0:inc %0 numalias letter_loop,%0:inc %0 numalias letter_len,%0:inc %0 numalias cut_base,%0:inc %0 numalias cut_head,%0:inc %0 numalias cut_rest,%0:inc %0 numalias cut_len,%0:inc %0 numalias cut2_base,%0:inc %0 numalias cut2_left,%0:inc %0 numalias cut2_right,%0:inc %0 numalias cut2_temp,%0:inc %0 defsub is_zenkaku defsub is_hankaku defsub letter_len defsub letter_num defsub cut_head_letter defsub cut_text defsub is_ja
パートB
;================== ; is_zenkaku ;================== ; 文字列を与え、その文字列の先頭の文字が全角かどうか判定する。 ; 第一引数:結果を受け取る数値変数 ; 第二引数:判定対象の文字列(変数) ; 結果は、0が半角、1が全角 ; 依存:なし *is_zenkaku getparam i%is_zen_result,$is_zen_target mov %%is_zen_result,0 cmp %is_zen_cmp,$is_zen_target,"゚": if %is_zen_cmp>0 mov %%is_zen_result,1:return cmp %is_zen_cmp,$is_zen_target,"。":notif %is_zen_cmp<0 return cmp %is_zen_cmp,$is_zen_target,"~": if %is_zen_cmp>0 mov %%is_zen_result,1:return return ;================== ; is_hankaku ;================== ; 文字列を与え、その文字列の先頭の文字が半角かどうか判定する。 ; 第一引数:結果を受け取る数値変数 ; 第二引数:判定対象の文字列(変数) ; 結果は、0が全角、1が半角 ; 依存:is_zenkaku *is_hankaku getparam i%is_zen_result,$is_zen_target is_zenkaku %%is_zen_result,$is_zen_target mov %%is_zen_result,1-%%is_zen_result return ;================== ; letter_len ;================== ; 文字列を与え、その文字列の先頭の文字が、1バイトか2バイトかを判定する。 ; 第一引数:結果を受け取る数値変数 ; 第二引数:判定対象の文字列(変数) ; 結果は、0が文字列無し、1が半角、2が全角 ; 依存:is_zenkaku *letter_len getparam i%is_zen_result,$is_zen_target mov %%is_zen_result,0 if $is_zen_target="" return is_zenkaku %%is_zen_result,$is_zen_target inc %%is_zen_result return ;================== ; letter_num ;================== ; 文字列を与え、その文字列が文字数でどれだけの長さになるかを返す。 ; 第一引数:結果を受け取る数値変数 ; 第二引数:判定対象の文字列(変数) ; 結果は、文字数 ; 依存:letter_len *letter_num getparam i%letter_result,$letter_base mov %%letter_result,0 ; 初期設定 if $letter_base="" return ; 空文字列なら、0を返す。 len %letter_base,$letter_base ; バイト長さを取得 if %letter_base=1 mov %%letter_result,1:return ; 1バイト長さなら、1を返す。 mov %letter_loop,0 ; 初期設定その2 *letter_num_loop mid $letter_loop,$letter_base,%letter_loop,1 ; 一文字を取得 letter_len %letter_len,$letter_loop ; その文字の全角半角判定 inc %%letter_result ; 一文字は一文字 add %letter_loop,%letter_len ; 文字のバイト数分ずらす。 if %letter_loop<%letter_base goto *letter_num_loop return ;================== ; cut_head_letter ;================== ; 文字列を与えると、1バイトか2バイトかを判別して、その先頭の文字を返す。 ; 第一引数:分割したい文字列 ; 第二引数:先頭の文字列を受ける文字列変数 ; 第三引数:先頭の文字を落とした残りを受ける文字列変数 ; 依存:letter_len ; 第一引数と第三引数を同じ文字列変数を使うと便利かも。 *cut_head_letter getparam $cut_base,s%cut_head,s%cut_rest mov $%cut_head,"" ; 初期設定 mov $%cut_rest,"" ; 初期設定 if $cut_base="" return ; ショートカット len %cut_base,$cut_base if %cut_base=1 mov $%cut_head,$cut_base:return ; ショートカットその2 letter_len %cut_len,$cut_base ; 先頭の文字の長さを取得。 if %cut_len=%cut_base mov $%cut_head,$cut_base:return ; ショートカットその3 ; それ以外ならば、 mid $%cut_head,$cut_base,0,%cut_len ; 先頭から1文字ないし2文字を取得 mid $%cut_rest,$cut_base,%cut_len,%cut_base-%cut_len ; 残りを格納 return ;================== ; cut_text ;================== ; 文字列と数値を与えると、その文字数で分割して返す。 ; 第一引数:分割したい文字列 ; 第二引数:何文字で分割するか。 ; 第三引数:先頭から第二引数の文字列 ; 第四引数:残りの文字列 ; 依存:cut_head_letter ; 数値を140にすると、Twitterに使える。 *cut_text getparam $cut2_base,%cut2_base,s%cut2_left,s%cut2_right mov $%cut2_left,"" mov $%cut2_right,"" if $cut2_base="" return ; ショートカット *cut_text_loop cut_head_letter $cut2_base,$cut2_temp,$cut2_base ; 分割して$cut2_tempに入れる。 add $%cut2_left,$cut2_temp if $cut2_base="" return dec %cut2_base if %cut2_base>0 goto *cut_text_loop mov $%cut2_right,$cut2_base ; 残りを入れる。 return ;================== ; is_ja ;================== ; 文字列を与え、その文字列に2byte文字が含まれているかどうかを返す。 ; 第一引数:結果を受け取る数値変数 ; 第二引数:判定対象の文字列(変数) ; 結果は、0が全て半角、1が全角が含まれる。 ; 依存:なし *is_ja getparam i%is_zen_result,$is_zen_target ; 結果を格納する変数,対象の文字列 mov %%is_zen_result,0 ; 結果を0で初期化 len %is_zen_len,$is_zen_target ; 対象の文字列の長さを取得 mov %is_zen_target,-1 ; 対象も文字列へのカーソル *is_ja_loop inc %is_zen_target ; カーソルを一つすすめる。 if %is_zen_len-2 < %is_zen_target return ; 残り文字数が2未満ならば、0で回答 mid $is_zen_len,$is_zen_target,%is_zen_target,2 ; カーソル位置から2文字を取得。 cmp %is_zen_cmp,$is_zen_len,"゚": if %is_zen_cmp>0 mov %%is_zen_result,1:return cmp %is_zen_cmp,$is_zen_len,"。":notif %is_zen_cmp<0 goto *is_ja_loop ; ループする。 cmp %is_zen_cmp,$is_zen_len,"~": if %is_zen_cmp>0 mov %%is_zen_result,1:return goto *is_ja_loop ; ループする。
何が変わったか。
なんか微妙な修正。それから、is_ja命令を追加した。
is_ja命令は、第2引数の文字列に日本語が混じっていれば1を、そうでなければ0を第一引数の変数に返す命令。
is_jaって何に使うの?
arc.nsaの中を2バイト文字のファイル名で探そうとするとバグります。その回避のため、実際に読み込む前に色々調査したり加工したりするのに必要です。忍者のように。