Search code examples
stringdelphidelphi-6

Delphi function for testing string present at position x


In a recent application that involved receiving strings over a serial link I found myself writing code like:

if (pos('needle', haystack) = 1) then ...

in order to check if a particular substring is at the begging of a string.

It struck me that the pos function is not ideal for this as it has no idea which location I'm looking for the substring to be in.

Is there a good function that does this?

Is there a more generalised function like IsSubStringAt(needle, haystack, position)?

I did think of using something like this:

function IsSubstrAt(const needle, haystack: string; position: Integer): Boolean;
var
  ii: integer;
begin
  result := true;
  for ii := 1 to length(needle) de begin
    if (haystack[poition + ii -1] <> needle[ii]) then begin
      result := false;
      break;
    end;
  end;
end;

with some error checking.

I was hoping to find a ready rolled answer.


Solution

  • Since you only want to look at one position, you can just form the substring and test that. Like this:

    function IsSubStringAt(const needle, haystack: string; position: Integer): Boolean;
    var
      substr: string;
    begin
      substr := Copy(haystack, position, Length(needle));
      Result := substr = needle;
    end;
    

    If performance was really critical then then you would want to perform the comparison in-place without creating a copy, and thereby performing heap allocation. You could use AnsiStrLComp for this.

    function IsSubStringAt(const needle, haystack: string; position: Integer): Boolean;
    begin
      if Length(haystack) - position + 1 >= Length(needle) then begin
        Result := AnsiStrLComp(
          PChar(needle), 
          PChar(haystack) + position - 1, 
          Length(needle)
        ) = 0;
      end else begin
        Result := False;
      end;
    end;
    

    If you want to check without senstivity to case, replace = with SameText in the first version, and replace AnsiStrLComp with AnsiStrLIComp in the second version.