StrUtils

unit StrUtils; //delphi5 有的函数,delphi7没有的一些函数
 
interface 
 
const 
  CR = #13; 
  LF = #10; 
 
{                                  } 
{  *** Pascal string functions *** } 
{                                  } 
 
{ AddBackSlash adds a trailing backslash to a string if one doesn't already } 
{ exist. } 
function AddBackSlash(const S: string): string; 
 
{ DecStrLen decrements the length of a string by the number specified. } 
procedure DecStrLen(var S: string; DecBy: Integer); 
 
{ GetCurLine returns the CR/LF delimited string of which the character } 
{ at index Position is an element. } 
function GetCurLine(const S: string; Position: Integer): string; 
 
{ GetStrAllocSize returns the memory allocation size of a given string. } 
function GetStrAllocSize(const S: string): Longint; 
 
{ GetStrRefCount returns the reference count of a given string. } 
function GetStrRefCount(const S: string): Longint; 
 
{ KillChars strips all characters out of string S that are contained in } 
{ constant character array A and returns result } 
function KillChars(const S: string; A: array of Char; CaseSensitive: Boolean): 
  string; 
 
{ LastPos finds the last occurance of SubStr in S } 
function LastPos(const SubStr, S: string): Integer; 
 
{ RealizeLength sets string length to null-terminated length. } 
procedure RealizeLength(var S: string); 
 
{ RemoveBackSlash removes a trailing backslash from a string if one is } 
{ present. } 
function RemoveBackSlash(const S: string): string; 
 
{ RemoveSpaces strips all spaces out of string S and returns result } 
function RemoveSpaces(const S: string): string; 
 
{ RverseStr reverses the characters in a string, and returns new string } 
function ReverseStr(const S: string): string; 
 
{                                  } 
{  *** PChar string functions ***  } 
{                                  } 
 
{ StrGetCurLine assumes StartPos is a pointer to a long string and    } 
{ CurPos points to any character in that string (up to TotalLen bytes } 
{ away from StartPos).  This procedure returns the CRLF-delimited     } 
{ line of text in LineStart which holds char CurPos^.  The length of  } 
{ that line is given by LineLen. } 
procedure StrGetCurLine(StartPos, CurPos: PChar; TotalLen: integer; 
  var LineStart: PChar; var LineLen: integer); 
 
{ StrLastPos finds the last occurance of Str2 in Str1 } 
function StrLastPos(Str1, Str2: PChar): PChar; 
 
{ StrIPos returns the first occurence of Str2 in Str1 with case insensitivity } 
function StrIPos(Str1, Str2: PChar): PChar; 
 
{ StrIScan returns the first occurance of Chr in Str with case insensitivity } 
function StrIScan(Str: PChar; Chr: Char): PChar; 
 
{ Reverses the characters in a string } 
procedure StrReverse(P: PChar); 
 
implementation 
 
uses SysUtils; 
 
type 
  TCharSet = set of Char; 
 
{                                  } 
{  *** Pascal string functions *** } 
{                                  } 
 
function AddBackSlash(const S: string): string; 
begin 
  Result := S; 
  if Result[Length(Result)] <> '\' then  // if last char isn't a backslash... 
    Result := Result + '\';              // make it so 
end; 
 
procedure DecStrLen(var S: string; DecBy: Integer); 
begin 
  SetLength(S, Length(S) - DecBy);       // decrement string length by DecBy 
end; 
 
function GetCurLine(const S: string; Position: Integer): string; 
var 
  ResP: PChar; 
  ResLen: integer; 
begin 
  StrGetCurLine(PChar(S), PChar(Longint(S) + Position - 1), Length(S), ResP, 
    ResLen); 
  SetString(Result, ResP, ResLen); 
end; 
 
function GetStrAllocSize(const S: string): Longint; 
var 
  P: ^Longint; 
begin 
  P := Pointer(S);                        // pointer to string structure 
  dec(P, 3);                              // 12-byte negative offset 
  Result := P^ and not $80000000 shr 1;   // ignore bits 0 and 31 
end; 
 
function GetStrRefCount(const S: string): Longint; 
var 
  P: ^Longint; 
begin 
  P := Pointer(S);                        // pointer to string structure 
  dec(P, 2);                              // 8-byte negative offset 
  Result := P^; 
end; 
 
function KillChars(const S: string; A: array of Char; CaseSensitive: Boolean): 
  string; 
var 
  CharSet: TCharSet; 
  i, count: integer; 
begin 
  CharSet := [];                         // empty character set 
  for i := Low(A) to High(A) do begin 
    Include(CharSet, A[i]);              // fill set with array items 
    if not CaseSensitive then begin      // if not case sensitive, then also 
      if A[i] in ['A'..'Z'] then 
        Include(CharSet, Chr(Ord(A[i]) + 32))  // include lower cased or 
      else if A[i] in ['a'..'z'] then 
        Include(CharSet, Chr(Ord(A[i]) - 32))  // include upper cased character 
    end; 
  end; 
  SetLength(Result, Length(S));          // set length to prevent realloc 
  count := 0; 
  for i := 1 to Length(S) do begin       // iterate over string S 
    if not (S[i] in CharSet) then begin  // add good chars to Result 
      Result[count + 1] := S[i]; 
      inc(Count);                        // keep track of num chars copies 
    end; 
  end; 
  SetLength(Result, count);              // set length to num chars copied 
end; 
 
function LastPos(const SubStr, S: string): Integer; 
var 
  FoundStr: PChar; 
begin 
  Result := 0; 
  FoundStr := StrLastPos(PChar(S), PChar(SubStr)); 
  if FoundStr <> nil then 
    Result := (Cardinal(Length(S)) - StrLen(FoundStr)) + 1; 
end; 
 
procedure RealizeLength(var S: string); 
begin 
  SetLength(S, StrLen(PChar(S))); 
end; 
 
function RemoveBackSlash(const S: string): string; 
begin 
  Result := S; 
  if Result[Length(Result)] = '\' then   // if last character is a backslash... 
    DecStrLen(Result, 1);                // decrement string length 
end; 
 
function RemoveSpaces(const S: string): string; 
begin 
  Result := KillChars(S, [' '], True); 
end; 
 
function ReverseStr(const S: string): string; 
begin 
  Result := S; 
  StrReverse(PChar(Result)); 
end; 
 
{                                  } 
{  *** PChar string functions ***  } 
{                                  } 
 
procedure StrGetCurLine(StartPos, CurPos: PChar; TotalLen: integer; 
                        var LineStart: PChar; var LineLen: integer); 
var 
  FloatPos, EndPos: PChar; 
begin 
  FloatPos := CurPos; 
  LineStart := nil; 
  repeat 
    if FloatPos^ = LF then 
    begin 
      dec(FloatPos); 
      if FloatPos^ = CR then 
      begin 
        inc(FloatPos, 2); 
        LineStart := FloatPos; 
      end; 
    end 
    else 
      dec(FloatPos); 
  until (FloatPos <= StartPos) or (LineStart <> nil); 
  if LineStart = nil then LineStart := StartPos; 
  FloatPos := CurPos; 
  EndPos := StartPos; 
  inc(EndPos, TotalLen - 1); 
  LineLen := 0; 
  repeat 
    if FloatPos^ = CR then 
    begin 
      inc(FloatPos); 
      if FloatPos^ = LF then 
      begin 
        dec(FloatPos, 2); 
        LineLen := FloatPos - LineStart + 1; 
      end; 
    end 
    else 
      inc(FloatPos); 
  until (FloatPos >= EndPos) or (LineLen <> 0); 
  if LineLen = 0 then 
    LineLen := integer(EndPos) - integer(LineStart); 
end; 
 
function StrIPos(Str1, Str2: PChar): PChar; 
{ Warning: this function is slow for very long strings. } 
begin 
  Result := Str1; 
  dec(Result); 
  repeat 
    inc(Result); 
    Result := StrIScan(Result, Str2^); 
  until (Result = nil) or (StrLIComp(Result, Str2, StrLen(Str2)) = 0); 
end; 
 
function StrIScan(Str: PChar; Chr: Char): PChar; 
asm 
  push  edi                 // save edi 
  push  eax                 // save eax (Str addr) 
  mov   edi, Str            // store Str in edi 
  mov   ecx, $FFFFFFFF      // max counter 
  xor   al, al              // null char in al 
  repne scasb               // search for null 
  not   ecx                 // ecx = length of Str 
  pop   edi                 // restore Str in edi 
  mov   al, Chr             // put Chr in al 
  cmp   al, 'a'             // if al is lowercase... 
  jb    @@1 
  cmp   al, 'z' 
  ja    @@1 
  sub   al, $20             // force al to uppercase 
@@1: 
  mov   ah, byte ptr [EDI]  // put char from Str in ah 
  cmp   ah, 'a'             // if al is lowercase... 
  jb    @@2 
  cmp   ah, 'z' 
  ja    @@2 
  sub   ah, $20             // force al to uppercase 
@@2: 
  inc   edi                 // inc to next char in string 
  cmp   al, ah              // are chars the same? 
  je    @@3                 // jump if yes 
  loop  @@1                 // loop if no 
  mov   eax, 0              // if char is not in string... 
  jne   @@4                 // go to end of proc 
@@3:                        // if char is in string... 
  mov   eax, edi            // move char position into eax 
  dec   eax                 // go back one character because of inc edi 
@@4: 
  pop   edi                 // restore edi 
end; 
 
function StrLastPos(Str1, Str2: PChar): PChar; 
var 
  Found: Boolean; 
begin 
  if (Str1 <> nil) and (Str2 <> nil) and (StrLen(Str1) >= StrLen(Str2)) then 
  begin 
    Found := False; 
    Result := Str1; 
    inc(Result, StrLen(Str1) - StrLen(Str2)); 
    repeat 
      if StrPos(Result, Str2) <> nil then 
        Found := True 
      else 
        dec(Result); 
    until (Result <= Str1) or Found; 
    if not Found then Result := nil; 
  end 
  else 
    Result := nil; 
end; 
 
procedure StrReverse(P: PChar); 
var 
  E: PChar; 
  c: char; 
begin 
  if StrLen(P) > 1 then begin 
    E := P; 
    inc(E, StrLen(P) - 1);          // E -> last char in P 
    repeat 
      c := P^;                      // store beginning char in temp 
      P^ := E^;                     // store end char in beginning 
      E^ := c;                      // store temp char in end 
      inc(P);                       // increment beginning 
      dec(E);                       // decrement end 
    until abs(Integer(P) - Integer(E)) <= 1; 
  end; 
end; 
 
posted @ 2021-01-04 13:15  ¥初心不改  阅读(87)  评论(0)    收藏  举报