〜 テキスト 〜
指定テキスト内の特定文字列を置換

poke系命令は特定メモリのデータを直接上書きするというもので、
置換前と置換後のバイト数が全く同一である必要がありますが、置換しない領域を一切触ることなく変更でき、
処理時に一時領域を確保する必要もありません。
しかし、置換後のサイズが、置換前のサイズよりも大きくなる、または小さくなる場合は、
一時領域を確保し、置換しない領域を切り出し編集する必要が出てきます。
下記のモジュールは上記の方法により、対象文字列内の特定文字列を一括変換するというものですが、
置換後のサイズが置換前のサイズよりも大きく、変数サイズを超えてしまう場合は、
HSP2はバッファオーバーフローエラーとなってしまいます。
HSP3以降は、変数サイズの自動拡張機能によりエラーとはなりませんが、
置換文字数が多い場合、度重なる自動拡張が行われることになりますので、作り上好ましくありません。
置換を行う前に、コチラのキーワード数を取得するモジュールを利用して、
「キーワード数×置換文字列のバイト差」を増やしておく等、十分なサイズを予め確保しましょう。
	

strrep 置換対象変数, 置換キー配列変数
置換対象変数置換する文字列を格納している変数を指定する。
置換キー配列変数要素0を置換後の文字列、要素1を置換前の文字列とした文字列型配列変数を指定する。

 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 strrep val, val
	mref s, 24 : mref keyword, 57
	i = 0, 0 // 検索開始位置, 検索結果
	strlen i.2, keyword.0
	strlen i.3, keyword.1
	strlen i.4, s
	sdim tmp, i.4
	repeat
		instr i.1, s, keyword.1, i.0
		if i.1 = -1 : break
		i += i.1
		strmid tmp, s, , i.0
		strlen i.4, s
		strmid s, s, i.0 + i.3, i.4 - i.0 - i.3
		s = tmp + keyword.0 + s
		i += i.2
	loop
	return
#global

	sdim string, 128 // もし変換後サイズが変数サイズを超える場合は大きめに確保しておくこと
	sdim word, 16, 2
	string = "すもももももももものうち"
	word = "も", "もも" // 要素0に置換後、要素1に置換前の文字列を指定する
	strrep string, word // 対象ワードを置き換える
	dialog string

strrep 置換対象変数, 置換後文字列, 置換前文字列
置換対象変数置換する文字列を格納している変数を指定する。
置換後文字列置換前文字列で指定したテキストを、ココで指定した文字列に置換する。
置換前文字列置換する文字列を指定する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#module
#deffunc strrep var s, str after, str before, local i
	repeat
		if instr(s, i, before) = -1 : break
		i += instr(s, i, before)
		s  = strmid(s, 0, i) + after + strmid(s, i + strlen(before), strlen(s) - i - strlen(before))
		i += strlen(after)
	loop
	return
#global

	sdim string, 128 // もし変換後サイズが変数サイズを超える場合は大きめに確保しておくこと
	string = "すもももももももものうち"
	word = "も", "もも"
	strrep string, word.0, word.1 // 対象ワードを置き換える
	dialog string
	end