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.
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.