16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"AnsiCopy, AnsiDelete"
この発言に対し以下のコメントが寄せられています
#00825 Satobe さん RE:AnsiCopy, AnsiDelete
みなさんこんにちは。
全角文字対応の Copy, Delete 関数です。
function Max(X, Y: Integer): Integer;
begin
Result := X;
if Y > X then Result := Y;
end;
function Min(X, Y: Integer): Integer;
begin
Result := X;
if X > Y then Result := Y;
end;
function AnsiDelete(var S: String; Index, Count: Integer): Integer;
var
I, L, LastIndex: Integer;
begin
// Delete の2バイト文字対応版
// Index が全角文字の2バイト目の場合は Index を1つ進める
// Index + Count - 1 が全角1バイト目の場合は Count を1つ戻す
// 実際に削除した文字のバイト数を返す
Result := 0;
L := Length(S);
if (Index < 1) or (L < Index) or (Count < 1) then
Exit;
// 削除される文字列の最後の文字インデックス
LastIndex := Min(L, Index + Count - 1);
// LastIndex が全角1バイト目を指す場合は1つ戻すための処理
I := 1;
while I <= L do
begin
// ここでは、半角文字と全角1バイト目が判別可能
if LastIndex <= I then
begin
// LastIndex が全角1バイト目の場合は一つ戻す
if (LastIndex = I) and (S[I] in [#$81..#$9F, #$E0..#$FC]) then
Dec(LastIndex);
// LastIndex が半角の場合は LastIndex = I となり
// LastIndex が全角2バイト目を指している場合は LastIndex < I と
// なるので、その場合は単にループを終了する
Break;
end;
if S[I] in [#$81..#$9F, #$E0..#$FC] then
Inc(I);
Inc(I);
end;
// 削除開始位置が全角2バイト目の場合は1つ進めるための処理
I := 1;
while I <= LastIndex do
begin
// ここでは、半角文字と全角1バイト目が判別可能
if Index <= I then
Break;
if S[I] in [#$81..#$9F, #$E0..#$FC] then
Inc(I);
Inc(I);
end;
Result := Max(0, LastIndex - I + 1);
if 0 < Result then
Delete(S, I, Result);
end;
function AnsiCopy(S: String; var Index, Count: Integer): String;
var
I, L, LastIndex: Integer;
begin
// Copy の2バイト文字対応版
// Index が全角文字の2バイト目の場合は Index を1つ進める
// Index + Count - 1 が全角1バイト目の場合は Count を1つ戻す
// 実際に Copy された Index, Count を取得出来る
Result := '';
L := Length(S);
if (Index < 1) or (L < Index) or (Count < 1) then
Exit;
// 取得される文字列の最後の文字インデックス
LastIndex := Min(L, Index + Count - 1);
// LastIndex が全角1バイト目を指す場合は1つ戻すための処理
I := 1;
while I <= L do
begin
// ここでは、半角文字と全角1バイト目が判別可能
if LastIndex <= I then
begin
// LastIndex が全角1バイト目の場合は一つ戻す
if (LastIndex = I) and (S[I] in [#$81..#$9F, #$E0..#$FC]) then
Dec(LastIndex);
// LastIndex が半角の場合は LastIndex = I となり
// LastIndex が全角2バイト目を指している場合は LastIndex < I と
// なるので、その場合は単にループを終了する
Break;
end;
if S[I] in [#$81..#$9F, #$E0..#$FC] then
Inc(I);
Inc(I);
end;
// 取得開始位置が全角2バイト目の場合は1つ進めるための処理
I := 1;
while I <= LastIndex do
begin
// ここでは、半角文字と全角1バイト目が判別可能
if Index <= I then
Break;
if S[I] in [#$81..#$9F, #$E0..#$FC] then
Inc(I);
Inc(I);
end;
Index := I;
Count := Max(0, LastIndex - Index + 1);
Result := Copy(S, Index, Count);
end;
本田勝彦
Original document by 本田勝彦 氏 ID:(VYR01647)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|