如何从字符串中删除任何字符(或子字符串)?

时间:2022-09-13 08:35:18

I use C# basically. There I can do:

我使用c#。在那里我能做什么:

string trimmed = str.Trim('\t');

to trim tabulation from the string str and return the result to trimmed.

要从字符串str修饰表并将结果返回到已修饰的表。

In delphi7 I found only Trim, that trims spaces.

在delphi7中,我只发现修剪,修剪空间。

How can I achieve the same functionality?

如何实现相同的功能?

6 个解决方案

#1


5  

This is a kind of procedure sometimes easier to create than to find where it lives :)

这是一种有时更容易创建的过程,而不是找到它所在的地方。

function TrimChar(const Str: string; Ch: Char): string;
var
  S, E: integer;
begin
  S:=1;
  while (S <= Length(Str)) and (Str[S]=Ch) do Inc(S);
  E:=Length(Str);
  while (E >= 1) and (Str[E]=Ch) do Dec(E);
  SetString(Result, PChar(@Str[S]), E - S + 1);
end;

#2


8  

There is string helper TStringHelper.Trim that accepts array of Char as optional parameter.

有字符串助手TStringHelper。可接受Char数组作为可选参数的修饰。

function Trim(const TrimChars: array of Char): string; overload;

So, you can use

所以,你可以使用

trimmed := str.Trim([#09]);

for your example. #09 here is ASCII code for Tab character.

你的例子。这里是制表符的ASCII码。

This function exists since at least Delphi XE3.

这个函数之所以存在,至少是因为Delphi XE3。

Hope it helps.

希望它可以帮助。

#3


3  

In Delphi the Trim function does not take parameters but it does trim other characters as well as spaces. Here's the code (from System.SysUtils in XE2, I don't think it has changed):

在Delphi中,Trim函数不接受参数,但它也会去除其他字符和空格。这是系统代码。XE2中的SysUtils,我认为它没有改变):

function Trim(const S: string): string;
var
  I, L: Integer;
begin
  L := Length(S);
  I := 1;
  if (L > 0) and (S[I] > ' ') and (S[L] > ' ') then Exit(S);
  while (I <= L) and (S[I] <= ' ') do Inc(I);
  if I > L then Exit('');
  while S[L] <= ' ' do Dec(L);
  Result := Copy(S, I, L - I + 1);
end;

It is trimming anything less than ' ' which would eliminate any control characters like tab, carriage return and line feed.

它正在修改任何小于' ' '的内容,以消除任何控制字符,如制表符、回车符和换行符。

#4


2  

Delphi doesn't provide a function that does what you want. The built-in Trim function always trims the same set of characters (whitespace and control characters) from both ends of the input string. Several answers here show the basic technique for trimming arbitrary characters. As you can see, it doesn't have to be complicated. Here's my version:

Delphi并没有提供你想要的功能。内置的Trim函数总是会从输入字符串的两端修剪相同的一组字符(空白和控制字符)。这里的几个答案展示了修剪任意字符的基本技术。正如你所看到的,这并不需要很复杂。这是我的版本:

function Trim(const s: string; c: Char): string;
var
  First, Last: Integer;
begin
  First := 1;
  Last := Length(s);
  while (First <= Last) and (s[First] = c) do
    Inc(First);
  while (First < Last) and (s[Last] = c) do
    Dec(last);
  Result := Copy(s, First, Last - First + 1);
end;

To adapt that for trimming multiple characters, all you have to do is change the second conditional term in each loop. What you change it to depends on how you choose to represent the multiple characters. C# uses an array. You could also put all the characters in a string, or you could use Delphi's native set type.

为了适应对多个字符的修改,您所要做的就是修改每个循环中的第二个条件项。您将其更改为什么取决于您选择如何表示多个字符。c#使用数组。您也可以将所有字符放在一个字符串中,或者您可以使用Delphi的本机集类型。

function Trim(const s: string; const c: array of Char): string;
// Replace `s[x] = c` with `CharInArray(s[x], c)`.

function Trim(const s: string; const c: string): string;
// Replace `s[x] = c` with `CharInString(s[x], s)`.

function Trim(const s: string; const c: TSysCharSet): string;
// Replace `s[x] = c` with `s[x] in c`.

The CharInArray and CharInString functions are easy to write:

CharInArray和CharInString函数易于编写:

function CharInArray(c: Char; ar: array of Char): Boolean;
var
  i: Integer;
begin
  Result := True;
  for i := Low(ar) to High(ar) do
    if ar[i] = c then
      exit;
  Result := False;
end;
// CharInString is identical, except for the type of `ar`.

Recall that as of Delphi 2009, Char is an alias for WideChar, meaning it's too big to fit in a set, so you wouldn't be able to use the set version unless you were guaranteed the input would always fit in an AnsiChar. Furthermore, the s[x] in c syntax generates warnings on WideChar arguments, so you'd want to use CharInSet(s[x], c) instead. (Unlike CharInArray and CharInString, the RTL provides CharInSet already, for Delphi versions that need it.)

回想一下,在Delphi 2009年,Char是WideChar的别名,这意味着它太大了,不适合放在一个集合中,所以您将无法使用set版本,除非您保证输入始终适合于AnsiChar。此外,c语法中的s[x]生成对WideChar参数的警告,因此您需要使用CharInSet(s[x], c)。(与CharInArray和CharInString不同,RTL已经为需要CharInSet的Delphi版本提供了CharInSet。)

#5


1  

You can use StringReplace:

您可以使用StringReplace:

var
  str:String;
begin
  str:='The_aLiEn'+Chr(VK_TAB)+'Delphi';

  ShowMessage(str);

  str:=StringReplace(str, chr(VK_Tab), '', [rfReplaceAll]);

  ShowMessage(str);
end;

This omits all Tab characters from given string. But you can improve it, if you want leading and trailing tabs to be removed then you can use Pos function also.

这省略了给定字符串中的所有制表符。但是您可以改进它,如果您想要删除前导和尾随标签,那么您也可以使用Pos函数。

Edit: For the comment asking how to do it with Pos, here it is:

编辑:关于如何使用Pos的评论,这里是:

var
  str:String;
  s, e: PChar;
begin
  str:=Chr(VK_TAB)+Chr(VK_TAB)+'The_aLiEn'+Chr(VK_TAB)+'Delphi'+Chr(VK_TAB)+Chr(VK_TAB);

  s:=PChar(str);

  while Pos(Chr(VK_TAB), s)=1 do inc(s);
  e:=s;
  inc(e, length(s)-1);
  while Pos(Chr(VK_TAB), e)=1 do dec(e);
  str:=Copy(s, 1, length(s)-length(e)+1);

  ShowMessage(str);
end;

It is of course the same approach by Maksee's and a bit more job to do as it is. But if there isn't much time to finish the work and if Pos is what you've thought first, then this is how it can be done. You, the programmer should and have to think about optimizations, not me. And if we're talking constraints of optimization, with a little tweak to replace Pos with char compare, this will run faster than Maksee's code.

当然,马凯的方法也是一样的,还有更多的工作要做。但是如果没有足够的时间完成这项工作,如果你首先想到的是Pos,那么这就是完成它的方法。你,程序员应该而且必须考虑优化,而不是我。如果我们讨论优化的约束,稍微调整一下用char compare替换Pos,这会比Maksee的代码运行得更快。

Edit for Substr search generalization:

编辑子str搜索泛化:

function TrimStr(const Source, SubStr: String): String;
var
  s, e: PChar;
  l: Integer;
begin
  s:=PChar(Source);
  l:=Length(SubStr);

  while Pos(SubStr, s)=1 do inc(s, l);
  e:=s;
  inc(e, length(s)-l);
  while Pos(SubStr, e)=1 do dec(e, l);
  Result:=Copy(s, 1, length(s)-length(e)+l);
end;

#6


0  

The JEDI JCL v2.7 provides these useful functions for what you need:

绝地JCL v2.7提供了以下有用的功能:

function StrTrimCharLeft(const S: string; C: Char): string; function StrTrimCharsLeft(const S: string; const Chars: TCharValidator): string; overload; function StrTrimCharsLeft(const S: string; const Chars: array of Char): string; overload; function StrTrimCharRight(const S: string; C: Char): string; function StrTrimCharsRight(const S: string; const Chars: TCharValidator): string; overload; function StrTrimCharsRight(const S: string; const Chars: array of Char): string; overload; function StrTrimQuotes(const S: string): string;

函数StrTrimCharLeft(const年代:字符串;C:Char):字符串;函数StrTrimCharsLeft(const年代:字符串;常量字符:TCharValidator):字符串;过载;函数StrTrimCharsLeft(const年代:字符串;const Chars: Char数组):string;过载;函数StrTrimCharRight(const年代:字符串;C:Char):字符串;函数StrTrimCharsRight(const年代:字符串;常量字符:TCharValidator):字符串;过载;函数StrTrimCharsRight(const年代:字符串;const Chars: Char数组):string;过载;函数StrTrimQuotes(const S: string): string;

#1


5  

This is a kind of procedure sometimes easier to create than to find where it lives :)

这是一种有时更容易创建的过程,而不是找到它所在的地方。

function TrimChar(const Str: string; Ch: Char): string;
var
  S, E: integer;
begin
  S:=1;
  while (S <= Length(Str)) and (Str[S]=Ch) do Inc(S);
  E:=Length(Str);
  while (E >= 1) and (Str[E]=Ch) do Dec(E);
  SetString(Result, PChar(@Str[S]), E - S + 1);
end;

#2


8  

There is string helper TStringHelper.Trim that accepts array of Char as optional parameter.

有字符串助手TStringHelper。可接受Char数组作为可选参数的修饰。

function Trim(const TrimChars: array of Char): string; overload;

So, you can use

所以,你可以使用

trimmed := str.Trim([#09]);

for your example. #09 here is ASCII code for Tab character.

你的例子。这里是制表符的ASCII码。

This function exists since at least Delphi XE3.

这个函数之所以存在,至少是因为Delphi XE3。

Hope it helps.

希望它可以帮助。

#3


3  

In Delphi the Trim function does not take parameters but it does trim other characters as well as spaces. Here's the code (from System.SysUtils in XE2, I don't think it has changed):

在Delphi中,Trim函数不接受参数,但它也会去除其他字符和空格。这是系统代码。XE2中的SysUtils,我认为它没有改变):

function Trim(const S: string): string;
var
  I, L: Integer;
begin
  L := Length(S);
  I := 1;
  if (L > 0) and (S[I] > ' ') and (S[L] > ' ') then Exit(S);
  while (I <= L) and (S[I] <= ' ') do Inc(I);
  if I > L then Exit('');
  while S[L] <= ' ' do Dec(L);
  Result := Copy(S, I, L - I + 1);
end;

It is trimming anything less than ' ' which would eliminate any control characters like tab, carriage return and line feed.

它正在修改任何小于' ' '的内容,以消除任何控制字符,如制表符、回车符和换行符。

#4


2  

Delphi doesn't provide a function that does what you want. The built-in Trim function always trims the same set of characters (whitespace and control characters) from both ends of the input string. Several answers here show the basic technique for trimming arbitrary characters. As you can see, it doesn't have to be complicated. Here's my version:

Delphi并没有提供你想要的功能。内置的Trim函数总是会从输入字符串的两端修剪相同的一组字符(空白和控制字符)。这里的几个答案展示了修剪任意字符的基本技术。正如你所看到的,这并不需要很复杂。这是我的版本:

function Trim(const s: string; c: Char): string;
var
  First, Last: Integer;
begin
  First := 1;
  Last := Length(s);
  while (First <= Last) and (s[First] = c) do
    Inc(First);
  while (First < Last) and (s[Last] = c) do
    Dec(last);
  Result := Copy(s, First, Last - First + 1);
end;

To adapt that for trimming multiple characters, all you have to do is change the second conditional term in each loop. What you change it to depends on how you choose to represent the multiple characters. C# uses an array. You could also put all the characters in a string, or you could use Delphi's native set type.

为了适应对多个字符的修改,您所要做的就是修改每个循环中的第二个条件项。您将其更改为什么取决于您选择如何表示多个字符。c#使用数组。您也可以将所有字符放在一个字符串中,或者您可以使用Delphi的本机集类型。

function Trim(const s: string; const c: array of Char): string;
// Replace `s[x] = c` with `CharInArray(s[x], c)`.

function Trim(const s: string; const c: string): string;
// Replace `s[x] = c` with `CharInString(s[x], s)`.

function Trim(const s: string; const c: TSysCharSet): string;
// Replace `s[x] = c` with `s[x] in c`.

The CharInArray and CharInString functions are easy to write:

CharInArray和CharInString函数易于编写:

function CharInArray(c: Char; ar: array of Char): Boolean;
var
  i: Integer;
begin
  Result := True;
  for i := Low(ar) to High(ar) do
    if ar[i] = c then
      exit;
  Result := False;
end;
// CharInString is identical, except for the type of `ar`.

Recall that as of Delphi 2009, Char is an alias for WideChar, meaning it's too big to fit in a set, so you wouldn't be able to use the set version unless you were guaranteed the input would always fit in an AnsiChar. Furthermore, the s[x] in c syntax generates warnings on WideChar arguments, so you'd want to use CharInSet(s[x], c) instead. (Unlike CharInArray and CharInString, the RTL provides CharInSet already, for Delphi versions that need it.)

回想一下,在Delphi 2009年,Char是WideChar的别名,这意味着它太大了,不适合放在一个集合中,所以您将无法使用set版本,除非您保证输入始终适合于AnsiChar。此外,c语法中的s[x]生成对WideChar参数的警告,因此您需要使用CharInSet(s[x], c)。(与CharInArray和CharInString不同,RTL已经为需要CharInSet的Delphi版本提供了CharInSet。)

#5


1  

You can use StringReplace:

您可以使用StringReplace:

var
  str:String;
begin
  str:='The_aLiEn'+Chr(VK_TAB)+'Delphi';

  ShowMessage(str);

  str:=StringReplace(str, chr(VK_Tab), '', [rfReplaceAll]);

  ShowMessage(str);
end;

This omits all Tab characters from given string. But you can improve it, if you want leading and trailing tabs to be removed then you can use Pos function also.

这省略了给定字符串中的所有制表符。但是您可以改进它,如果您想要删除前导和尾随标签,那么您也可以使用Pos函数。

Edit: For the comment asking how to do it with Pos, here it is:

编辑:关于如何使用Pos的评论,这里是:

var
  str:String;
  s, e: PChar;
begin
  str:=Chr(VK_TAB)+Chr(VK_TAB)+'The_aLiEn'+Chr(VK_TAB)+'Delphi'+Chr(VK_TAB)+Chr(VK_TAB);

  s:=PChar(str);

  while Pos(Chr(VK_TAB), s)=1 do inc(s);
  e:=s;
  inc(e, length(s)-1);
  while Pos(Chr(VK_TAB), e)=1 do dec(e);
  str:=Copy(s, 1, length(s)-length(e)+1);

  ShowMessage(str);
end;

It is of course the same approach by Maksee's and a bit more job to do as it is. But if there isn't much time to finish the work and if Pos is what you've thought first, then this is how it can be done. You, the programmer should and have to think about optimizations, not me. And if we're talking constraints of optimization, with a little tweak to replace Pos with char compare, this will run faster than Maksee's code.

当然,马凯的方法也是一样的,还有更多的工作要做。但是如果没有足够的时间完成这项工作,如果你首先想到的是Pos,那么这就是完成它的方法。你,程序员应该而且必须考虑优化,而不是我。如果我们讨论优化的约束,稍微调整一下用char compare替换Pos,这会比Maksee的代码运行得更快。

Edit for Substr search generalization:

编辑子str搜索泛化:

function TrimStr(const Source, SubStr: String): String;
var
  s, e: PChar;
  l: Integer;
begin
  s:=PChar(Source);
  l:=Length(SubStr);

  while Pos(SubStr, s)=1 do inc(s, l);
  e:=s;
  inc(e, length(s)-l);
  while Pos(SubStr, e)=1 do dec(e, l);
  Result:=Copy(s, 1, length(s)-length(e)+l);
end;

#6


0  

The JEDI JCL v2.7 provides these useful functions for what you need:

绝地JCL v2.7提供了以下有用的功能:

function StrTrimCharLeft(const S: string; C: Char): string; function StrTrimCharsLeft(const S: string; const Chars: TCharValidator): string; overload; function StrTrimCharsLeft(const S: string; const Chars: array of Char): string; overload; function StrTrimCharRight(const S: string; C: Char): string; function StrTrimCharsRight(const S: string; const Chars: TCharValidator): string; overload; function StrTrimCharsRight(const S: string; const Chars: array of Char): string; overload; function StrTrimQuotes(const S: string): string;

函数StrTrimCharLeft(const年代:字符串;C:Char):字符串;函数StrTrimCharsLeft(const年代:字符串;常量字符:TCharValidator):字符串;过载;函数StrTrimCharsLeft(const年代:字符串;const Chars: Char数组):string;过载;函数StrTrimCharRight(const年代:字符串;C:Char):字符串;函数StrTrimCharsRight(const年代:字符串;常量字符:TCharValidator):字符串;过载;函数StrTrimCharsRight(const年代:字符串;const Chars: Char数组):string;过载;函数StrTrimQuotes(const S: string): string;