←前へ 次へ→ 機能別Q&A 質問番号順Q&A 秀丸エディタQ&A集トップ

[HMM0073A]

●文字列をバイト単位ではなく文字単位で扱う

Q. 「strlen」等の文字列操作関数はバイト単位となっていますが、文字単位で扱うことはできないでしょうか?1バイト文字と2バイト文字が混在している時に、とても困ります。

A. 秀丸の関数「ascii」は先頭文字が2バイト文字の場合に値を2バイトで返すので、ビット演算を使って2バイト文字かどうかを判断することで、可能です。
なお、秀丸マクロでは文字コードをSHIFT-JISで扱っているため、文字列中の任意の場所の文字コードを判別するには、文字列の先頭から順番に検索する必要があります。

// サンプルマクロ(ここから)
$Str = "AABBCC";

call leftstr2 $Str, 2;
message "左2文字=[" + $$return + "]";

call rightstr2 $Str, 2;
message "右2文字=[" + $$return + "]";

call midstr2 $Str, 2, 2;
message "中2文字=[" + $$return + "]";

endmacro;

//----------------------------------
// 文字列の左側部分
//
// (引数) $$1: 文字列、##2: 文字数
// (返り値) $$return: 文字列
//----------------------------------
leftstr2:

call midstr2 $$1, 0, ##2;
return $$return;
//----------------------------------
// 文字列の右側部分
//
// (引数) $$1: 文字列、##2: 文字数
// (返り値) $$return: 文字列
//----------------------------------//
rightstr2:
call strlen2 $$1;
##Pos = ##return - ##2;
if( ##Pos < 0 )
{
##Pos = 0;
}
call midstr2 $$1, ##Pos, ##2;
return $$return;
//--------------------------------------
// 文字列の中央部分
// (引数) $$1: 文字列、##2: 取得位置、##3: 文字数
// (返り値) $$return: 文字列
//--------------------------------------
midstr2:
$$Str = "";
##StrLen = strlen( $$1 );
##I = 0;
##J = 0;
while( ##I < ##StrLen )
{
if( ##J >= ##2 )
{
break;
}
if( ( ascii( midstr( $$1, ##I, 2 ) ) & 0xff00 ) != 0 )
{ // 2バイト文字
##I = ##I + 2;
}
else
{
##I = ##I + 1;
}
##J = ##J + 1;
}
##J = 0;
while( ##I < ##StrLen )
{
if( ##J >= ##3 )
{
break;
}
$$Wk = midstr( $$1, ##I, 2 );
if( ( ascii( $$Wk ) & 0xff00 ) != 0 )
{ // 2バイト文字
##I = ##I + 2;
}
else
{
$$Wk = midstr( $$1, ##I, 1 );
##I = ##I + 1;
}
$$Str = $$Str + $$Wk;
##J = ##J + 1;
}
return $$Str;
//------------------------------------------
// 文字列の長さ
// (引数) $$1: 文字列
// (返り値) ##return: 文字列の長さ
//------------------------------------------
strlen2:
##StrLen = strlen( $$1 );
##I = 0;
##StrLen2 = 0;
while( ##I < ##StrLen )
{
if( ( ascii( midstr( $$1, ##I, 2 ) ) & 0xff00 ) != 0 )
{ // 2バイト文字
##I = ##I + 2;
}
else
{
##I = ##I + 1;
}
##StrLen2 = ##StrLen2 + 1;
}
return ##StrLen2;
// サンプルマクロ(ここまで)


←前へ 次へ→ 機能別Q&A 質問番号順Q&A 秀丸エディタQ&A集トップ