这是一个不基于 asm 的替代方案。它也适用于 64 位应用程序。
function PosExUBound(const SubStr, Str: UnicodeString; Offset,EndPos: Integer): Integer; overload;
var
I, LIterCnt, L, J: NativeInt;
PSubStr, PS: PWideChar;
begin
L := Length(SubStr);
if (EndPos > Length(Str)) then
EndPos := Length(Str);
{ Calculate the number of possible iterations. Not valid if Offset < 1. }
LIterCnt := EndPos - Offset - L + 1;
{- Only continue if the number of iterations is positive or zero (there is space to check) }
if (Offset > 0) and (LIterCnt >= 0) and (L > 0) then
begin
PSubStr := PWideChar(SubStr);
PS := PWideChar(Str);
Inc(PS, Offset - 1);
Dec(L);
I := 0;
J := L;
repeat
if PS[I + J] <> PSubStr[J] then
begin
Inc(I);
J := L;
Dec(LIterCnt);
if (LIterCnt < 0)
then Exit(0);
end
else
if (J > 0) then
Dec(J)
else
Exit(I + Offset);
until false;
end;
Result := 0;
end;
我将把它作为练习来实现AnsiString
重载版本。
顺便说一句,XE3 中的purepascal
部分功能写得有点糟糕。Pos()
请参阅QC111103 Inefficient loop in Pos() for purepascal。喜欢就给它投票吧。