说我有以下字符串:
s := 'This , is, the Delphi , World!';
我想要以下输出:
Result := 'This,is,the Delphi,World!';
基本上我需要一个例程,如果它们出现在逗号字符(这是我的分隔符)之前或之后,它会删除 ALL 空格 ON 的出现,在其他字符之间留下完整的空格词语的
非常感谢任何帮助。
您如何看待这个解决方案?
function RemoveSpacesAroundDelimiter(var aString: string; aDelimiter:
string): string;
begin
while AnsiContainsText(aString, aDelimiter + ' ') do
begin
aString := StringReplace(aString, ', ', aDelimiter, [rfReplaceAll, rfIgnoreCase]);
end;
while AnsiContainsText(aString, ' ' + aDelimiter) do
begin
aString := StringReplace(aString, ' ' + aDelimiter, aDelimiter, [rfReplaceAll, rfIgnoreCase]);
end;
Result := aString;
end;
的Fabio
答案 0 :(得分:9)
听起来像是TStringList的任务。
function UltraTrim(Value: string): string;
var
sl: TStringList;
i: Integer;
begin
sl := TStringList.Create;
try
// Prevent the stringlist from using spaces as delimiters too.
sl.StrictDelimiter := True;
// Set the comma separated text.
sl.CommaText := Value;
// Trim each item.
for i := 0 to sl.Count -1 do
sl[i] := Trim(sl[i]);
// Concat back to comma separated string.
Result := sl.CommaText;
finally
sl.Free;
end;
end;
答案 1 :(得分:4)
快速版可能是:
function RemoveSpacesAroundDelimiter(const aString: string; aDelimiter: char = ','): string;
var S, D, D2: PChar;
begin
SetLength(result,length(aString));
if aString<>'' then
begin
S := pointer(aString);
D := pointer(result);
while S^<>#0 do
begin
if S^=' ' then
begin
D2 := D;
repeat
inc(S);
D^ := ' ';
inc(D);
until S^<>' ';
if S^=#0 then
break;
if S^=aDelimiter then
D := D2; // trim spaces before comma
end;
D^ := S^;
if (S[0]=aDelimiter) and (S[1]=' ') then
repeat inc(S) until S^<>' ' else // trim spaces after comma
inc(S);
inc(D);
end;
SetLength(result,D-pointer(result));
end;
end;
一些测试代码:
assert(RemoveSpacesAroundDelimiter('one two,three')='one two,three');
assert(RemoveSpacesAroundDelimiter('one two , three')='one two,three');
assert(RemoveSpacesAroundDelimiter('one,two,three')='one,two,three');
assert(RemoveSpacesAroundDelimiter('one , two, three')='one,two,three');
答案 2 :(得分:3)
将字符逐个复制到目标缓冲区中,但查找空格和分隔符,并记住将非空格字符复制到的最后位置。如果您看到一个空格,并且您复制的最后一个非空格是分隔符,则跳过该空格。如果它是一个空格,并且您复制的最后一个字符不是分隔符,则将其复制到目标,但请记住您添加的最后一个非空格。这样,如果您稍后看到分隔符,则可以返回并覆盖它。
function RemoveSpacesAroundDelimiter(const AString: string; ADelimiter: Char): string;
var
c: Char;
dest: Integer;
LastNonSpace: Integer;
HaveDelimiter: Boolean;
begin
Assert(ADelimiter <> ' ');
SetLength(Result, Length(AString));
dest := 1;
LastNonSpace := 0;
HaveDelimiter := False;
for c in AString do begin
if (c = ' ') and HaveDelimiter then
continue; // Skip this character
if c = ADelimiter then begin
dest := LastNonSpace + 1;
HaveDelimiter := True;
end else
HaveDelimiter := False;
Result[dest] := c;
if c <> ' ' then
LastNonSpace := dest;
Inc(dest);
end;
SetLength(Result, dest - 1);
end;
答案 3 :(得分:3)
如果您使用的是Delphi XE或更高版本,则可以使用正则表达式在一行代码中轻松完成此操作。
program regex;
{$APPTYPE CONSOLE}
uses
RegularExpressions;
const
Input = 'This , is, the Delphi , World!';
begin
Writeln(TRegEx.Replace(Input, ' *, *', ','));
Readln;
end.
当然,这不是所提供解决方案中运行速度最快的,但也许对您来说无关紧要。
答案 4 :(得分:1)
您可以使用正则表达式。您希望找到前面或后跟任意数量空格的分隔符,并将其全部替换为分隔符的单个副本。
function RemoveSpacesAroundDelimiter(const AString: string; const ADelimiter: string): string;
var
re: TPerlRexEx;
begin
re := TPerlRegEx.Create;
try
re.RegEx := '\s*' + TPerlRegEx.EscapeRegExChars(ADelimiter) + '\s*';
re.Subject := AString;
re.Replacement := TPerlRegEx.EscapeRegExChars(ADelimiter);
re.ReplaceAll;
Result := re.Subject;
finally
re.Free;
end;
end;
较新的Delphi版本可以使用内置的RegularExpressionCore单元。较旧的版本可以使用等效的PerlRegEx unit from Jan Goyvaerts。
Mick之前发布的an answer证明了这一点,但是他删除了它,因为他得到了正则表达式错误(删除所有空格而不仅仅是与分隔符相邻的空格)。
答案 5 :(得分:1)
更简单,最简单的方法是使用正则表达式。您需要的最后一件事是一个巨大的复杂代码块来解决这样一个简单的问题。不幸的是我现在没有Delphi,我无法测试这段代码,但是如果它不是这样的话,它非常接近:
s := 'This , is, the Delphi , World!';
RegEx := TRegEx.Create('[ ]*,[ ]*');
CleanStr := RegEx.Replace(s, ',');
答案 6 :(得分:1)
我有此解决方案:
slValores.DelimitedText := StringReplace(sListSummary,' ','',[rfReplaceAll]);
答案 7 :(得分:0)
我认为这值得补充,因为它适用于早期版本的Delphi,其中stringlist解决方案(我喜欢)不会。
我相信它的速度相当快,阅读和理解起来相当简单。
function TForm1.UltraTrim(const InString : String; Delim : Char) : String;
var
Buf : String;
i : Integer;
Token : String;
begin
Result := '';
if Trim(InString) <> '' then begin
i := 1;
Buf := StringReplace(InString, Delim, #0, [rfReplaceAll]) + #0;
while i < Length(Buf) do begin
Token := StrPas(@Buf[i]);
i := i + Length(Token) + 1;
Result := Result + Delim + Trim(Token);
end;
Result := Copy(Result,2,Length(Result));
end;
end;
答案 8 :(得分:0)
使用Jedi代码库,@ GolezTrol的回答可以使用单行重新编写。
function UltraTrim(Value: string): string;
begin
Result := JclStringList.Split(Value, ',').Trim.Join(',')
end;
答案 9 :(得分:0)
使用此功能:
function MBTrim(iStr :string):string;
const CTc= 3{Conditions Count};
CT :array[0..(CTc-1),0..1]of string= ( (' ,', ','), (', ', ','), (' ', ' ') );
var i :Integer;
begin
for i := 0 to CTc-1 do while Pos(CT[i,0], iStr) > 0 do
iStr:= StringReplace(iStr, CT[i,0], CT[i,1], [rfReplaceAll, rfIgnoreCase]);
Result:= Trim(iStr);
end;
您可以简单地添加其他条件。
例如,我添加(' ', ' ')
来转换单词之间的空格,如:
'This , is, the Delphi , World!'
答案 10 :(得分:-2)
再次改变。
while (pos(', ',s)>0) or (pos(' ,',s)>0) do begin
s := StringReplace(s, ', ', ',', [rfReplaceAll]);
s := StringReplace(s, ' ,', ',', [rfReplaceAll]); end;
确定所有Delphi版本。