String 如何删除字符周围的空格?
假设我有以下字符串:String 如何删除字符周围的空格?,string,delphi,String,Delphi,假设我有以下字符串: s := 'This , is, the Delphi , World!'; 我想要以下输出: Result := 'This,is,the Delphi,World!'; 基本上,我需要一个例程,该例程仅当空格出现在逗号字符(这是我的分隔符)之前或之后时,才会删除所有出现的空格,在其他单词之间保留完整的空格 非常感谢您的帮助 你认为这个解决方案怎么样 function RemoveSpacesAroundDelimiter(var aString:
s := 'This , is, the Delphi , World!';
我想要以下输出:
Result := 'This,is,the Delphi,World!';
基本上,我需要一个例程,该例程仅当空格出现在逗号字符(这是我的分隔符)之前或之后时,才会删除所有出现的空格,在其他单词之间保留完整的空格
非常感谢您的帮助
你认为这个解决方案怎么样
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听起来像是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;
又变了一次
while (pos(', ',s)>0) or (pos(' ,',s)>0) do begin
s := StringReplace(s, ', ', ',', [rfReplaceAll]);
s := StringReplace(s, ' ,', ',', [rfReplaceAll]); end;
适用于所有Delphi版本。快速版本可以是:
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;
将字符逐个复制到目标缓冲区中,但要查找空格和分隔符,并记住上次将非空格字符复制到的位置。如果看到一个空格,并且复制的最后一个非空格是分隔符,则跳过该空格。如果它是一个空格,而您复制的最后一个字符不是分隔符,则将其复制到目标,但请记住您添加的最后一个非空格。这样,如果稍后看到分隔符,可以返回并覆盖它
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;
函数RemoveSpacesAroundDelimiter(常量AString:string;ADelimiter:Char):string;
变量
c:半焦;
dest:整数;
LastNonSpace:整数;
分隔符:布尔;
开始
断言(限定符“”);
设置长度(结果、长度(收敛));
目的地:=1;
LastNonSpace:=0;
HaveDelimiter:=False;
对于c,请开始
如果(c='')和分隔符
继续;//跳过此字符
如果c=0,则开始
dest:=LastNonSpace+1;
HaveDelimiter:=True;
结束其他
HaveDelimiter:=False;
结果[dest]:=c;
如果是c,那么
LastNonSpace:=dest;
公司(目的地);
结束;
设置长度(结果,dest-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版本可以使用内置单元。较旧的版本可以使用等效版本
以前发布过演示这一点的文章,但他删除了它,因为他把正则表达式搞错了(删除所有空格,而不仅仅是与分隔符相邻的空格)。最简单、最简单的方法是使用正则表达式。要解决这样一个简单的问题,最不需要的就是一个庞大复杂的代码块。不幸的是,我现在没有Delphi,我无法测试这段代码,但如果它与此完全不同,那么它非常接近:
s := 'This , is, the Delphi , World!';
RegEx := TRegEx.Create('[ ]*,[ ]*');
CleanStr := RegEx.Replace(s, ',');
如果您使用的是Delphi XE或更高版本,您可以在一行代码中使用正则表达式轻松地完成这项工作
program regex;
{$APPTYPE CONSOLE}
uses
RegularExpressions;
const
Input = 'This , is, the Delphi , World!';
begin
Writeln(TRegEx.Replace(Input, ' *, *', ','));
Readln;
end.
当然,这不是提供的解决方案中运行最快的,但可能这对您来说并不重要。我认为这是值得添加的,因为它将适用于早期版本的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;
函数TForm1.UltraTrim(const InString:String;Delim:Char):String;
变量
Buf:字符串;
i:整数;
令牌:字符串;
开始
结果:='';
如果修剪(安装)’,则开始
i:=1;
Buf:=StringReplace(InString,Delim,#0,[rfReplaceAll])+#0;
当我
使用绝地密码库,@GolezTrol的答案可以用一行代码重新格式化
function UltraTrim(Value: string): string;
begin
Result := JclStringList.Split(Value, ',').Trim.Join(',')
end;
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!'
我有一个解决方案:
slValores.DelimitedText := StringReplace(sListSummary,' ','',[rfReplaceAll]);
我不知道delphi,但您可以使用逗号作为分隔符拆分字符串,然后对每个生成的子字符串调用Trim(),然后再次组装字符串(可能有一个连接方法可用于字符串列表)哪个版本的delphi?如果您有XE或更高版本,您可以使用正则表达式来执行此操作。我更喜欢使用stringReplace的解决方案,即使所有情况都不受影响。您的解决方案更通用,因为您可以更改分隔符,但我的解决方案更轻。只是一句话:我认为在使用函数时,你不需要把字符串作为函数中的VAR参数传递,除非你想把它用作函数或类似的过程。- 1号,它可以删除所有的空白,并且与<代码>修饰符(<)/代码>相同,但也将删除“Delphi”和“Delphi”之间的空白。@ SasHER,修剪(S)仅删除开头和结尾的空格。如果分隔符前后有多个空格,则不起作用,请参阅我的原始帖子以获得重新访问的版本。@philnext:多个空格如何?可能是最有用的组件除了它不是组件之外,我完全同意。TStringList多次救了我的命。这也删除了字符串开头和结尾的空格。不过,我认为它们不应该被删除,因为它们没有分隔符。@Uwe,这个问题在两个方面与你的说法相矛盾。首先,它要求删除空格“仅当它们出现在逗号字符之前或之后时”。大写和斜体是一个非常严格的要求。其次,法比奥的代码只删除了分隔符旁边的空格。你对“共识”这个词有着奇怪的理解,@Hugh。在我提出这一点之前,我完全看不到关于这是否是法比奥想要的东西的讨论,所以我不确定你们怎么会认为有共识。即使以前有过,现在也没有了。我添加了自己的“快速”答案,但删除了它,因为你的答案更快。小心。此代码假定字符串不包含任何
#0
字符。@文本字符串不应包含任何#0字符,否则将破坏许多Windows API。谁会在这样的Unicode字符串中间放置一个0?@ CasmiPund我喜欢你的版本。这是一个清晰的样本
slValores.DelimitedText := StringReplace(sListSummary,' ','',[rfReplaceAll]);