改行を含んだ文字列から空行を削除したいのですが、
var
SL: TStringList;
i: Integer;
begin
SL := TStringList.Create;
try
SL.Text := Value; // Valueに文字列が入っている
for i := SL.Count - 1 downto 0 do
if SL[i] = '' then
SL.Delete(i);
Value := SL.Text;
finally
SL.Free;
end;
end;
この方法だと文字列の最後に改行が無いときうまくいきません。
どうすれば空行だけを削除できるでしょうか?
それと、TStringListを使わない方法がありましたら教えてください。
私は普段for文は使わないので良く分かりませんが
SL.Count-1の部分がSL.Countだけで良いような気がします
var
SL:・TStringList;
i:・Integer;
begin
SL・:=・TStringList.Create;
try
SL.Text・:=・Value;
i:=0;
while・i・<・SL.Count・do
begin
if・SL[i]・=・''・then
SL.Delete(i);
end;
Value・:=・SL.Text;
finally
SL.Free;
end;
end;
ですかな
何か文字化けしてますね
> この方法だと文字列の最後に改行が無いときうまくいきません。
そうなの? 試したところではうまくいくようですけど。
>・この方法だと文字列の最後に改行が無いときうまくいきません。
たぶん最後の行まで実行されて無いだけだとおもいます
var
s:string;
begin
while ansipos(#13#10#13#10,s) do
begin
StringReplace(s,#13#10#13#10,#13#10,[rfReplaceAll]);
end;
if s[length(s)-1]+s[length(s)] = #13#10 then
begin
s:=leftstr(s,length(s)-2);
end;
end;
ミッス!!
危険、無限ループ
StringReplace(s,#13#10#13#10,#13#10,[rfReplaceAll]);
ではなく
s:=StringReplace(s,#13#10#13#10,#13#10,[rfReplaceAll]);
それだと、#13#10#13#10#13#10が、#13#10#13#10になり、空行が残ります。
# 無限ループにはなりませんよ。
# 処理後の場所は処理されません。
また、先頭の空行は、#13#10のみですので、別途処理が必要です。
最後の行が改行の時問題であれば、最後にダミーの行を追加してからTStringListに入れれば対処できますね。
るるとん@Kさん、失礼しました。
ちゃんと処理されていましたね。
よく見ず発言してました。
こんなのを作っていました。文字列が大きいと遅いと思います。細かくはチェックしていません。
function DelEmptyLine(const str: String): String;
var
s: String;
p: PCHAR;
prev: Char;
begin
s := AdjustLineBreaks(str, tlbsLF);//#$Aに変更
p := PCHAR(s);
Result := '';
prev := ' ';
while p^=#10 do Inc(p);
while p^ <> #0 do
begin
if (prev=#10) and (p^=#10) then
begin
Inc(p);
Continue;
end;
Result := Result + p^;
prev := p^;
Inc(p);
end;
Result := AdjustLineBreaks(Result);
end;
作って気がついたのですが、文字列最後の改行を、最後に空行があると見なすのでしょうか。
# 上に書いたプロシージャでは、最後の改行は空行とは見なしていません。
>また、先頭の空行は、#13#10のみですので、別途処理が必要です。
これでOK
var
s:string;
begin
while ansipos(#13#10#13#10,s)>0 do
begin
s:=StringReplace(s,#13#10#13#10,#13#10,[rfReplaceAll]);
end;
if s[length(s)-1]+s[length(s)] = #13#10 then
begin
s:=leftstr(s,length(s)-2);
end;
if ansipos(#13#10,s)=1 then
begin
s:=stringreplace(s,#13#10,'',[])
end;
end;
> 私は普段for文は使わないので良く分かりませんが
> SL.Count-1の部分がSL.Countだけで良いような気がします
for文にしたのは一番高速だと教わったからです。
繰り返しの回数がわかっているときはfor文を使う方が良いらしいです。
> 文字列最後の改行を、最後に空行があると見なすのでしょうか。
自信は無いのですが、空行というのは「改行コードの前に文字が無い行」
ではないかと思います。
るるとん@Kさん、コードを書いてくださってありがとうございます。
ですが、同じ方法を以前試したことがあり、文字列が大きいと遅くて
実用になりませんでした。
にしのさんの方法を使わせていただきます。
どうもありがとうございました。
ツイート | ![]() |