0
votes

I have searched and tried a couple of loops which are supposed to remove symbols from a string, I need this because certain locations can have a "/" or other type of symbol and I need it removed since FTP will think it's a folder, and I need the string in a name.

The String 'place' varies from the persons current working location, for example there's a 'place' = "S/A StorageRoom", the '/' part of the String make's FTP think that it's a subfolder.

For now I'm using this, which I think is pretty large and could use 'shortening':

   place := StringReplace(place, ',', '', [rfReplaceAll]);
   place := StringReplace(place, '.', '', [rfReplaceAll]);
   place := StringReplace(place, '/', '', [rfReplaceAll]);
   place := StringReplace(place, '!', '', [rfReplaceAll]);
   place := StringReplace(place, '@', '', [rfReplaceAll]);
   place := StringReplace(place, '#', '', [rfReplaceAll]);
   place := StringReplace(place, '$', '', [rfReplaceAll]);
   place := StringReplace(place, '%', '', [rfReplaceAll]);
   place := StringReplace(place, '^', '', [rfReplaceAll]);
   place := StringReplace(place, '&', '', [rfReplaceAll]);
   place := StringReplace(place, '*', '', [rfReplaceAll]);
   place := StringReplace(place, '''', '', [rfReplaceAll]);
   place := StringReplace(place, '"', '', [rfReplaceAll]);
   place := StringReplace(place, ';', '', [rfReplaceAll]);
   place := StringReplace(place, '_', '', [rfReplaceAll]);
   place := StringReplace(place, '(', '', [rfReplaceAll]);
   place := StringReplace(place, ')', '', [rfReplaceAll]);
   place := StringReplace(place, ':', '', [rfReplaceAll]);
   place := StringReplace(place, '|', '', [rfReplaceAll]);
   place := StringReplace(place, '[', '', [rfReplaceAll]);
   place := StringReplace(place, ']', '', [rfReplaceAll]);
   place := StringReplace(place, '\', '', [rfReplaceAll]);

Edit: I'm currently using RAD Studio 10.1 Berlin

2
What Delphi version are you using? Recent versions can do this more easily than older ones, so it is relevant. Please add a tag for the specific Delphi version (7, 2007, etc.). - Ken White
Added in the text, currently I'm using RAD Studio 10.1 Berlin - Relinkvent
I added the tag for you. Can you edit your post to provide a sample of the string that would be in place? You can do this pretty easily with a regular expression, but the specific one you will need will depend on the text you're actually working with, so samples would be helpful. - Ken White
@KenWhite I added an example - Relinkvent

2 Answers

3
votes

In a quest to avoid unnecessary heap allocations, here is a variant of @Ancaron's answer that only does one allocation and a final size reduction in order to produce the answer.

The trick is to preallocate the resulting string at the beginning, and then fill it up with accepted characters. At the end, adjust the resulting string length.

program TestStripChars;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function StripChars (const Text : string; const InValidChars : SysUtils.TSysCharSet) : string;
var
  i,j : Integer;
begin
  SetLength(Result,Length(Text));  // Preallocate result maximum length
  j := 0;  // Resulting string length counter
  for i := 1 to Length(Text) do begin
    if not CharInSet(Text[i],InValidChars) then begin
      Inc(j);
      Result[j] := Text[i];
    end;
  end;
  SetLength(Result,j); // Set result actual length
end;

var
  place : String;
begin
  place := 'Hell$$o D.,e.$lphi';
  place := StripChars(place,[',','.','$']);
  WriteLn(place);
  ReadLn;
end.

From a comment it looks like the OP is using a compiler setting with zero based string handling.

Here is a function that handles both scenarios:

function StripChars ( const Text : string; const InValidChars : SysUtils.TSysCharSet) : string;
var
  i,j,zbsAdj : Integer;
begin
  SetLength(Result,Length(Text));  // Preallocate result maximum length
  j := 0; // Resulting string length counter
  zbsAdj := 1-Low(String); // Handles zero based string offset
  for i := Low(Text) to High(Text) do begin
    if not CharInSet(Text[i],InValidChars) then begin
      Inc(j);
      Result[j-zbsAdj] := Text[i];
    end;
  end;
  SetLength(Result,j); // Set result actual length
end;
0
votes

You cold just use a function like

function StripChars ( const Text : string; InValidChars : TSetOfChar ) : string;
var
  S : string;
  i : integer;
begin
  Result := '';
  if Length(Text) > 0 then
  begin
    S := '';
    for i := 1 to length ( Text ) do
      if not CharInSet(Text[i],InValidChars) then  
        S := S + Text [ i ];
    Result := S;
  end;
end;

and then only call

place := StripChars(place,[',','.', and so on]);