Delphi5を使っているのですが、
Trim関数の削除対象にて全角スペースは削除されないようです。
全角スペースも削除対象にするにはどうしたらよいでしょうか?
ご指導お願いします。
ShowMessage(StringReplace('hoge ほげ hoge ほげ', ' ', '', [rfReplaceAll]));
> ShowMessage(StringReplace('hoge ほげ hoge ほげ', ' ', '', [rfReplaceAll]));
失礼ですが、Trimとは動作が違っているのではないですか?
(ヘルプより)
Trim関数は文字列から先頭部分および末尾部分の空白と制御文字を取り除きます。
あ〜!StringReplace!
盲点でした。頭が固かったようです。。。
deldelさん、ご指導ありがとうございました。
>傍観者様
確かに・・・
処理の目的によっては、これでいいのですが、
やはりTrimで大文字スペースを削除したいです。
//自分で関数を作るのが一番早いんじゃないでしょうか
const
ZenkakuSpace = ' ';
function MBTrimRight(s : string) : string;
var
i : Integer;
begin
i := Length(s);
while i >= 1 do
begin
case ByteType(s,i) of
mbSingleByte:
if s[i] > #$20 then
Break;
mbLeadByte:
Break;
mbTrailByte:
if (s[i] = ZenkakuSpace[2]) and (s[i-1] = ZenkakuSpace[1]) then
Dec(i)
else
Break;
end;
Dec(i);
end;
Result := Copy(s,1,i);
end;
function MBTrimLeft(s : string) : string;
var
i : Integer;
begin
i := 1;
while i < Length(s) do
begin
case ByteType(s,i) of
mbSingleByte:
if s[i] > #$20 then
Break;
mbLeadByte:
if (s[i] = ZenkakuSpace[1]) and (s[i+1] = ZenkakuSpace[2]) then
Inc(i)
else
Break;
mbTrailByte:
Break;
end;
Inc(i);
end;
Result := Copy(s,i,MaxInt);
end;
function MBTrim(s : string) : string;
begin
Result := MBTrimLeft(MBTrimRight(s));
end;
>木星人様
SysUtilsのTrim関数を改造して、別名で関数にする事にします。
Delphiはまだまだ初心者レベルなので、ソース参考にさせて頂きます。
ご指導ありがとうございました。
ぢゃ、これは?
function Trim2(S: string): string;
begin
if Copy(S, 1, 2) = ' ' then S := Copy(S, 3, Length(S));
if Copy(S, Length(S) - 1, 2) = ' ' then S := Copy(S, 1, Length(S) - 2);
Result := S;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('<' + Trim2(' hogeほげ ') + '>');
ShowMessage('<' + Trim2('hogeほげ ') + '>');
ShowMessage('<' + Trim2(' hogeほげ') + '>');
ShowMessage('<' + Trim2('hogeほげ') + '>');
ShowMessage('<' + Trim2(' hoge ほげ') + '>');
end;
> Trim2
両端の全角スペースを取り除く関数になっていませんか?
全角スペースが両端にあるとは限らないですよね。
Trim2関数は文字列から先頭部分および末尾部分の全角スペースを取り除きます。
deldelさん
(' hogeほげ ')
の処理〜!
木星人さんのレスをちゃんと読みましょう。
傍観者さん、メラトニンさん、おおぼけでした。
すみませんm(_`_)m
皆様、色々ご指導ありがとうございます。
こんなんが出来ました。
早速テストしてみます。
function TrimMB(const S: string): string;
var
tmpS: String;
begin
tmpS := S;
while (Copy(tmpS, 1, 1) = ' ') and (Copy(tmpS, 1, 2) = ' ') do
begin
if Copy(tmpS, 1, 1) = ' ' then
tmpS := Copy(tmpS, 2, Length(tmpS));
if Copy(tmpS, 1, 2) = ' ' then
tmpS := Copy(tmpS, 3, Length(tmpS));
end;
while (Copy(tmpS, Length(tmpS), 1) = ' ') and (Copy(tmpS, Length(tmpS) -1, 2) = ' ') do
begin
if Copy(S, Length(S), 1) = ' ' then
S := Copy(S, 1, Length(S) - 1);
if Copy(S, Length(S) - 1, 2) = ' ' then
S := Copy(S, 1, Length(S) - 2);
end;
Result := tmpS;
end;
以下ではだめでしたね。
ShowMessage('<' + TrimMB(' hoge ほげ ') + '>');
木星人さんので、ばっちりだと思いますが・・・?
さきほどのソースは、凡ミスだらけでした。
修正したソースです。いい感じで動いてます。
木星人様、deldel様のソースを参考に作りました。
他の皆様もご指摘ありがとうございました。
{*** 以下ソース ***}
function TForm1.TrimMB(const S: string): string;
var
tmpS: String;
begin
tmpS := S;
while (Copy(tmpS, 1, 1) = ' ') or (Copy(tmpS, 1, 2) = ' ') do
begin
if Copy(tmpS, 1, 1) = ' ' then
tmpS := Copy(tmpS, 2, Length(tmpS));
if Copy(tmpS, 1, 2) = ' ' then
tmpS := Copy(tmpS, 3, Length(tmpS));
end;
while (Copy(tmpS, Length(tmpS), 1) = ' ') or (Copy(tmpS, Length(tmpS) -1, 2) = ' ') do
begin
if Copy(tmpS, Length(tmpS), 1) = ' ' then
tmpS := Copy(tmpS, 1, Length(tmpS) - 1);
if Copy(S, Length(S) - 1, 2) = ' ' then
tmpS := Copy(tmpS, 1, Length(tmpS) - 2);
end;
Result := tmpS;
end;
みなさん...こういうときって
将来の汎用性を考えて手続き書かない?
全角だけじゃなくて、全ての文字で
動作するように対応しておきたくなったり
先頭と末端指定も書きたくなったり、、、
それにファーストテストも実施するべき。
そうしておくとバグが減らせる。
このスレで起きてたような凡ミスも防止できるし
関数の信頼性やリファクタリングのような応用にもつながるよ。
const
EmptyStr: WideString = '';
function TrimLeftChar(S: WideString; Table: WideString): WideString;
var
i: Integer;
WriteIndex: Integer;
TrimFlag: Boolean;
begin
SetLength(Result, Length(S));
WriteIndex := 0;
TrimFlag := True;
for i := 1 to Length(S) do
begin
if not (TrimFlag and (1<=Pos(S[i], Table))) then
begin
TrimFlag := False;
Inc(WriteIndex);
Result[WriteIndex] := S[i];
end;
end;
SetLength(Result, WriteIndex);
{ -----------------------------------
//低速だがコードが短い方の実装
begin
while (S<>EmptyStr) and (1<=Pos(S[1], Table)) do
Delete(S, 1, 1);
Result := S;
end;
//----------------------------------- }
end;
function TrimRightChar(S: WideString; Table: WideString): WideString;
var
i: Integer;
WriteIndex: Integer;
begin
Result := S;
WriteIndex := Length(Result);
for i := Length(S) downto 1 do
begin
if (1<=Pos(S[i], Table)) then
begin
Dec(WriteIndex);
end else
begin
break;
end;
end;
SetLength(Result, WriteIndex);
{ -----------------------------------
//低速だがコードが短い方の実装
begin
while (S<>EmptyStr) and (1<=Pos(S[Length(S)], Table)) do
Delete(S, Length(S), 1);
Result := S;
end;
//----------------------------------- }
end;
function TrimChar(S: WideString; Table: WideString): WideString;
begin
Result := TrimLeftChar(TrimRightChar(S, Table), Table);
end;
procedure Check(A, B: String);
begin
if not(A = B) then
begin
raise Exception.Create('エラーです ' + A + ':' + B);
end;
end;
procedure testTrimLeftChar;
begin
Check('あ', TrimLeftChar(' あ', ' '));
Check('う', TrimLeftChar(' う', ' '));
Check('か', TrimLeftChar('あいうえおああいいか', 'あいうえお'));
Check('X', TrimLeftChar(' YY X', ' Y'));
Check('789', TrimLeftChar('012346789', '6543210'));
Check('ABCXYZ', TrimLeftChar('XXYYZZABCXYZ', 'XYZ'));
Check('', TrimLeftChar('XXYYZZABCXYZ', 'XYZABC'));
Check('AAA'#9, TrimLeftChar(#9'AAA'#9, #9));
Check(#9, TrimLeftChar('AAA'#9, 'A'));
Check(#9'AAA', TrimLeftChar(#13#10#9'AAA', #13#10));
Check(#13#10, TrimLeftChar(#9'AAA'#13#10, #9'A'));
Check('123', TrimLeftChar('123', ''));
end;
procedure testTrimRightChar;
begin
Check(' ', TrimRightChar(' あ', 'あ'));
Check('あいうえお', TrimRightChar('あいうえおああいいか', 'かいあ'));
Check('う', TrimRightChar('う ', ' '));
Check(' YY', TrimRightChar(' YY X', ' X'));
Check('012', TrimRightChar('012346789', '346789'));
Check('XXYYZZABC', TrimRightChar('XXYYZZABCXYZ', 'XYZ'));
Check('', TrimRightChar('XXYYZZABCXYZ', 'XYZABC'));
Check(#9'AAA', TrimRightChar(#9'AAA'#9, #9));
Check(#9, TrimRightChar(#9'AAA', 'A'));
Check(#9'AAA', TrimRightChar(#9'AAA'#13#10, #13#10));
Check(#13#10, TrimRightChar(#13#10#9'AAA', #9'A'));
Check('123', TrimRightChar('123', ''));
end;
procedure testTrimChar;
begin
Check('ABC', TrimChar('123467829ABC5212694192', '0123456789'));
Check('', TrimChar('123467829ABC5212694192', 'ABC0123456789'));
Check('かきくけこ', TrimChar('あいうえああいいかきくけこおおえういあい', 'あいうえお'));
Check('AAA', TrimChar(#9'AAA'#9, #9));
Check(#9, TrimChar(#9'AAA', 'A'));
Check(#9'AAA', TrimChar(#9'AAA'#13#10, #13#10));
Check(#13#10, TrimChar(#9'AAA'#13#10, #9'A'));
Check('123', TrimChar('123', ''));
end;
ツイート | ![]() |