Studying.com
Studying.com

Reputation: 119

Trying to remove a certain character from a string until the string only has x number of characters

I'm trying to remove a certain character from a string until the string only has x number of characters

So what I would like to achieve is

c:\folder\new\stuff\all\more\hello\awesome\to.dll

becomes

c:\folder\new\

By deleting one character at a time until the string posses 3 x '\'

{or how ever many backslashes I require it to posses since it wont be the same every time.}

So far I have tried:

function RemoveLastPart(var s: string; I : integer): string;
begin
  repeat
    delete(s, length(s),1)
  until (pos ('\',s) = I) and (s[length(s)]='\');
  result := s;
end;

and

function RemoveStr(var s: string; I : integer): string;
 begin
   while (pos ('\',s) = I)  do
    begin
   delete(s, length(s),1);
   result := s;
 end
 end;

but this wouldn't work because your path could still be

c:\folder\new\stuff vs c:\folder\new\

I'm guessing I'm using pos incorrectly. I thought if a string posses '\' then do something.

Since I never know how long the path will be or what folders it may or may not contain , it makes it a bit tricky.

I have also tried (pos ('\',s) < I) and increasing I by 1

So if I wanted I to be 3 I would say (pos ('\',s) < 4)

edited..............

Thanks for all the reply's

I will never know how many backslashes it will need .... I have a source folder which changes all the time

I then have a destination folder which also changes all the time.
the source folder (E.G c:\test) and the destination folder (E.G D:\Search Results)

The source folder is scanned for file types .. once a matching type is found (E.G c:\test\somefolder\anotherfolder.exe) I replace the source with the destination (E.G D:\Search Results\somefolder\anotherfolder.exe).

I then use a function to count both the source folders backslashes and the search results backslashes so

D:\Search Results\ = two backslashes(2) and D:\Search Results\somefolder\anotherfolder.exe = four backslashes(4)

if we the take 4-2+1 = 3

this is where I am stuck ...

I now know how many backslashes I need to copy the whole source directory.

so I need 3 back slashes

if we count backwards we get

D:\Search Results\somefolder\anotherfolder.exe D:\Search Results\somefolder\anotherfolder (this is wrong, this is why I added until (pos ('\',s) = I) and (s[length(s)]='\'); )

it would be better to count forwards so we get

D:\Search Results\somefolder\anotherfolder.exe D:\Search Results\somefolder\

thanks once again for all the replys. I haven't tried any of the suggested yet I will look into all of them and see if I can make something work.

Upvotes: 1

Views: 3138

Answers (2)

SilverWarior
SilverWarior

Reputation: 8386

Since you are only looking for specific characters you might also use another approach by simply iterating over all characters in string and counting how many times have you already found specific character.

Here is the code for achieving this;

//This function returns desired substring as result and thus does not modiffy input 
//string
//Use this function when it is required for your InputStr to remain intact for further
//processing
function ExtractSubString(InputStr: String; SearchedChar: Char; Count: Integer): String;
var Pos: Integer;
    TimesFound: Integer;
begin
  //Set initial values to local variables
  TimesFound := 0;
  //Set the default result of the method
  //While this is not needed with string results it is still good practice
  //Setting default result is required with most other result types so you don't
  //end up with uninitialized result which can have random value stored in it.
  Result := '';
  //Iterate through all characters in a string
  //NOTE: On moobile platforms strings are Zero-based so modiffy the code acordingly
  //to start with Pos 0
  for Pos := 1 to Length(InputStr) do
  begin
    //Check if specific character matches the one we are looking for
    if InputStr[Pos] = SearchedChar then
    begin
      //Increase the counter which stores how many times have we already found
      //desired character
      TimesFound := TimesFound+1;
      //Check if we found desirecd character enough times
      if TimesFound = Count then
      begin
        //Copy desired part of the input string to result
        Result := Copy(InputStr,0,Pos);
        //Use break command to break out of the loop prematurely
        Break;
      end;
    end;
  end;
end;


//This procedure modifies existing string instead of making a new shortened string
//You need to provide existing string variable as InputStr parameter
//Use only if you need to process string only once othervise use ExtractSubstring
procedure ShortenString(var InputStr: String; SearchedChar: Char; Count: Integer);
var Pos: Integer;
    TimesFound: Integer;
begin
  //Set initial values to local variables
  TimesFound := 0;
  //Iterate through all characters in a string
  //NOTE: On moobile platforms strings are Zero-based so modiffy the code acordingly
  //to start with Pos 0
  for Pos := 1 to Length(InputStr) do
  begin
    //Check if specific character matches the one we are looking for
    if InputStr[Pos] = SearchedChar then
    begin
      //Increase the counter which stores how many times have we already found
      //desired character
      TimesFound := TimesFound+1;
      //Check if we found desirecd character enough times
      if TimesFound = Count then
      begin
        //Adjust the length of the string and thus leaving out all the characters 
        //after desired length
        SetLength(InputStr,Pos);
        //Use break command to break out of the loop prematurely
        Break;
      end;
    end;
  end;
end;

Upvotes: 3

Tom Brunberg
Tom Brunberg

Reputation: 21045

Use PosEx repeatedly as many times as you want the backslash to occur in the result. When you have then found the nth, use SetLength() to chop the string, or Copy() if you want to preserve the original string and return the shortened string as a function result, e.g.:

function ChopAtNthBackslash(const s: string; n: integer):string;
var
  i, k: integer;
begin
  k := 0;
  for i := 1 to n do
  begin
    k := PosEx('\', s, k+1);
    if k < 1 then Exit('');
  end;
  Result := Copy(s, 1, k);
end;

Upvotes: 2

Related Questions