Search code examples
freepascallazarus

Traversing strings for multiple instances of substrings - freepascal or delphi


Platform : Lazarus 1.1, FreePascal 2.7.1, Win 7 32-bit.

I have a string value as follows:

FileName[12345][45678][6789].jpg

By default (assume this is default behaviour 0), my program currently pulls out the last set of numbers from the last pair of square brackets to the farthest right of the filename, i.e. 6789. It does so using this code:

if chkbxOverrideUniqueID.Checked then
   IDOverrideValue := StrToInt(edtToggleValue.Text);   
// User is happy to find the right most unique ID
if not chkbxOverrideUniqueID.Checked then      
  LastSquareBracket := RPos(']', strFileName);
  PreceedingSquareBracket := RPosEx('[', strFileName, LastSquareBracket) + 1;
  strFileID := AnsiMidStr(strFileName, PreceedingSquareBracket, LastSquareBracket - PreceedingSquareBracket)
else // User doesn't want to find the rightmost ID. 
  // and now I am stuck! 

However, I have now added an option for the user to specify a non-default behaviour. e.g if they enter '1', that means "look for the first ID in from the farthest right ID". e.g. [45678], because [6789] is default behaviour 0, remember. If they enter 2, I want it to find [12345].

My question : How do I adapt the above code to achieve this, please?


Solution

  • The following code will return just the numeric value between brackets:

    uses
      StrUtils;
    
    function GetNumber(const Text: string; Index: Integer): string;
    var
      I: Integer;
      OpenPos: Integer;
      ClosePos: Integer;
    begin
      Result := '';
      ClosePos := Length(Text) + 1;
      for I := 0 to Index do
      begin
        ClosePos := RPosEx(']', Text, ClosePos - 1);
        if ClosePos = 0 then
          Exit;
      end;
      OpenPos := RPosEx('[', Text, ClosePos - 1);
      if OpenPos <> 0 then
        Result := Copy(Text, OpenPos + 1, ClosePos - OpenPos - 1);
    end;
    

    If you'd like that value including those brackets, replace the last line with this:

    Result := Copy(Text, OpenPos, ClosePos - OpenPos + 1);