〜 テキスト 〜
文字列内の指定文字を除去

変数内テキストの一部を除去したい場合、通常は「新変数 = 除去前部文字列 + 除去後部文字列」とします。
別のやり方として、mesbox命令等のエディットコントロールを利用して除去する方法ですが、
これが優れていると言うわけではありません。方法の1つとして考えてください。
オブジェクトを使い、指定範囲内の文字列を削除すると、後に続くテキストが自動的に前へ来ますね。
その動きを見て、使えるかもと思った次第であります。
サンプルモジュールでは、不可視領域にオブジェクトを配置し、自動的に指定文字列を削っていきます。
そして、最後にその一時オブジェクトを消去して、出来上がった文字列を返します。
HSP2以前では、この方法で簡単に実現できましたが、HSP3からは少々厄介な問題が出ました。
HSP3からは、オブジェクト内の文字数カウントが機種依存するようなのです。
XPまで?、がHSP2と同じくバイト単位で、XP以降?、が文字単位であるようで、
HSP内の命令に問題はありませんが、sendmsg命令でオブジェクトとやり取りする際に影響します。
今回のTipsでは具体的に、指定位置から指定バイト数を選択・削除する部分が、
環境により、HSP3側モジュールで正常動作しなくなってしまうのです。
対策として、内部処理コードが文字数単位のUnicodeとなるmanifestリソースを組み込まない、
もしくは、リソースをいじくるツールを使って除去するという方法があります。
他の対策として、OSバージョンを確認しておいて、XP以降なら文字数単位で処理するとよいでしょう。
HSP3側のサンプルモジュールは、XP以降用として文字数単位で処理しています。
98や2000、Me等では逆に正常に動作しなくなっていると思われますので、
当Tipsを参考に考えている方は、事前にバージョンチェックを行って、
HSP2ロジック(内部の使用命令もHSP3版に変更)と切り分けるようにしてみてはどうでしょうか。
	

removechar 対象変数, 除去文字列
対象変数除去したい文字列が入った文字列型変数を指定する。
除去文字列除去する文字列を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#module
#deffunc removechar val, str
	mref s, 24 : mref string, 33
	null=""
	cx = csrx : cy = csry
	pos 0, -dispy : mesbox s : tmpid = stat
	pos cx, cy
	repeat
		instr chk, s, string
		if chk = -1 : break
		strlen chkend, string : chkend += chk
		objsend tmpid, 0x00B1, chk, chkend, 1 // 選択
		objsend tmpid, 0x00C2, 0, null, 0     // 削除
	loop
	clrobj tmpid, tmpid
return
#global

	sdim data, 128
	data  = "となりのきゃくは よく かきくう きゃくだ\n"
	data += "あおまきがみ あかまきがみ きまきがみ"
	dchr  = "き"
	pos 10,  10 : mes data
	pos 10,  80 : mes "除去データ:" + dchr
	removechar data, dchr // 指定文字列から指定文字列を削除する
	pos 10, 130 : mes data
	stop

受取先 = removechar(対象変数, 除去文字列)
受取先除去した後の文字列の格納先を指定する。
対象変数除去したい文字列が入った文字列型変数を指定する。
除去文字列除去する文字列を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#module
#defcfunc removechar str string, str string2, local tmp, local s, local null, local cx, local cy, local tmpid, local sels, local sele
	sdim tmp, strlen(string) * 2 + 1
	s = string
	null = ""
	cx = ginfo_cx : cy = ginfo_cy
	pos 0, -ginfo_dispy : mesbox s : tmpid = stat
	pos cx, cy
	repeat
		chk = instr(s, , string2)
		if chk = -1 : break
		cnvstow tmp, s
		// 文字単位で開始位置を処理する
		sels = 0
		repeat chk
			sels++ : if peek(tmp, sels * 2 + 1) { continue cnt + 2 }
		loop
		// 文字単位で終了位置を処理する
		sele = sels
		repeat strlen(string2)
			sele++ : if peek(tmp, sele * 2 + 1) { continue cnt + 2 }
		loop
		sendmsg objinfo(tmpid, 2), 0x00B1, sels, sele // 選択
		sendmsg objinfo(tmpid, 2), 0x00C2, 0, ""      // 削除
	loop
	clrobj tmpid, tmpid
	return s
#global

	data  = "となりの きゃくは よく かきくう きゃくだ\n"
	data += "あおまきがみ あかまきがみ きまきがみ"
	dchr  = "き"
	pos 10, 10 : mes data
	pos 10, 50 : mes "除去データ:" + dchr
	pos 10, 70 : mes "["+removechar(data, dchr)+"]" // 指定文字列から指定文字列を削除する