📄 jclstrings.pas
字号:
end; if I < Len then begin N := Pos(S[I + 1], OctDigits) - 1; if N >= 0 then begin Inc(I); Val := Val * 8 + N; end; end; end; {if val > 255 then raise EJclStringError.CreateResRec(@RsNumericConstantTooLarge);} Result := Result + Chr(Val); end;begin Result := ''; I := 1; Len := Length(S); while I <= Len do begin if not ((S[I] = '\') and (I < Len)) then Result := Result + S[I] else begin Inc(I); // Jump over escape character case S[I] of 'a': Result := Result + AnsiBell; 'b': Result := Result + AnsiBackspace; 'f': Result := Result + AnsiFormFeed; 'n': Result := Result + AnsiLineFeed; 'r': Result := Result + AnsiCarriageReturn; 't': Result := Result + AnsiTab; 'v': Result := Result + AnsiVerticalTab; '\': Result := Result + '\'; '"': Result := Result + '"'; '''': Result := Result + ''''; // Optionally escaped '?': Result := Result + '?'; // Optionally escaped 'x': if I < Len then // Start of hex escape sequence HandleHexEscapeSeq else // '\x' at end of AnsiString is not escape sequence Result := Result + '\x'; '0'..'7': // start of octal escape sequence HandleOctEscapeSeq; else // no escape sequence Result := Result + '\' + S[I]; end; end; Inc(I); end;end;//--------------------------------------------------------------------------------------------------function StrLower(const S: AnsiString): AnsiString;begin Result := S; StrLowerInPlace(Result);end;//--------------------------------------------------------------------------------------------------procedure StrLowerInPlace(var S: AnsiString); assembler;asm // StrCase(Str, LoOffset) XOR EDX, EDX // MOV EDX, LoOffset JMP StrCaseend;//--------------------------------------------------------------------------------------------------procedure StrLowerBuff(S: PAnsiChar); assembler;asm // StrCaseBuff(S, LoOffset) XOR EDX, EDX // MOV EDX, LoOffset JMP StrCaseBuffend;//--------------------------------------------------------------------------------------------------procedure StrMove(var Dest: AnsiString; const Source: AnsiString; const ToIndex, FromIndex, Count: Integer);begin // Check strings if (Source = '') or (Length(Dest) = 0) then Exit; // Check FromIndex if (FromIndex <= 0) or (FromIndex > Length(Source)) or (ToIndex <= 0) or (ToIndex > Length(Dest)) or ((FromIndex + Count - 1) > Length(Source)) or ((ToIndex + Count - 1) > Length(Dest)) then Exit; // Move Move(Source[FromIndex], Dest[ToIndex], Count);end;//--------------------------------------------------------------------------------------------------function StrPadLeft(const S: AnsiString; Len: Integer; C: AnsiChar): AnsiString;var L: Integer;begin L := Length(S); if L < Len then Result := StringOfChar(C, Len - L) + S else Result := S;end;//--------------------------------------------------------------------------------------------------function StrPadRight(const S: AnsiString; Len: Integer; C: AnsiChar): AnsiString;var L: Integer;begin L := Length(S); if L < Len then Result := S + StringOfChar(C, Len - L) else Result := S;end;//--------------------------------------------------------------------------------------------------function StrProper(const S: AnsiString): AnsiString;begin Result := S; StrProperBuff(PChar(Result));end;//--------------------------------------------------------------------------------------------------procedure StrProperBuff(S: PAnsiChar);begin if (S <> nil) and (S^ <> #0) then begin StrLowerBuff(S); S^ := CharUpper(S^); end;end;//--------------------------------------------------------------------------------------------------function StrQuote(const S: AnsiString; C: AnsiChar): AnsiString;var L: Integer;begin L := Length(S); Result := S; if L > 0 then begin if Result[1] <> C then begin Result := C + Result; Inc(L); end; if Result[L] <> C then Result := Result + C; end;end;//--------------------------------------------------------------------------------------------------function StrRemoveChars(const S: AnsiString; const Chars: TSysCharSet): AnsiString;var Source, Dest: PChar;begin SetLength(Result, Length(S)); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); while (Source <> nil) and (Source^ <> #0) do begin if not (Source^ in Chars) then begin Dest^ := Source^; Inc(Dest); end; Inc(Source); end; SetLength(Result, (Longint(Dest) - Longint(PChar(Result))) div SizeOf(AnsiChar));end;//--------------------------------------------------------------------------------------------------function StrKeepChars(const S: AnsiString; const Chars: TSysCharSet): AnsiString;var Source, Dest: PChar;begin SetLength(Result, Length(S)); UniqueString(Result); Source := PChar(S); Dest := PChar(Result); while (Source <> nil) and (Source^ <> #0) do begin if Source^ in Chars then begin Dest^ := Source^; Inc(Dest); end; Inc(Source); end; SetLength(Result, (Longint(Dest) - Longint(PChar(Result))) div SizeOf(AnsiChar));end;//--------------------------------------------------------------------------------------------------function StrRepeat(const S: AnsiString; Count: Integer): AnsiString;var L: Integer; P: PChar;begin L := Length(S); SetLength(Result, Count * L); P := Pointer(Result); while Count > 0 do begin Move(Pointer(S)^, P^, L); P := P + L; Dec(Count); end;end;//--------------------------------------------------------------------------------------------------function StrRepeatLength(const S: AnsiString; Const L: Integer): AnsiString;var Count: Integer; LenS: Integer; P: PChar;begin Result := ''; LenS := Length(S); if LenS > 0 then begin Count := L div LenS; if Count * LenS < L then Inc(Count); SetLength(Result, Count * LenS); P := Pointer(Result); while Count> 0 do begin Move(Pointer(S)^, P^, LenS); P := P + LenS; Dec(Count); end; if Length(S) > L then SetLength(Result, L); end;end;//--------------------------------------------------------------------------------------------------{ Temporary replacement of StrReplace. Basic algorithm is the same except that it has been simplified a little. This version is a little slower than the one below but at least it works. Someone will have to go over this sometime. }// case insensitive StrReplaceprocedure StrReplaceCS(var S: AnsiString; const Search, Replace: AnsiString; Flags: TReplaceFlags);var ResultStr: string; { result string } SourcePtr: PChar; { pointer into S of character under examination } SourceMatchPtr: PChar; { pointers into S and Search when first character has } SearchMatchPtr: PChar; { been matched and we're probing for a complete match } ResultPtr: PChar; { pointer into Result of character being written } SearchLength, { length of search string } ReplaceLength, { length of replace string } ResultLength: Integer; { length of result string (maximum, worst-case scenario) } C: Char; { first character of search string }begin //if (S = '') or (Search = '') then Exit; { avoid having to call Length() within the loop } SearchLength := Length(Search); ReplaceLength := Length(Replace); { initialize result string to maximum (worst case scenario) length } if Length(Search) >= ReplaceLength then ResultLength := Length(S) else ResultLength := ((Length(S) div Length(Search)) + 1) * Length(Replace); SetLength(ResultStr, ResultLength); { get pointers to begin of source and result } ResultPtr := PChar(ResultStr); SourcePtr := PChar(S); C := Search[1]; { while we haven't reached the end of the string } while True do begin { copy characters until we find the first character of the search string } while (SourcePtr^ <> C) and (SourcePtr^ <> #0) do begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; { did we find that first character or did we hit the end of the string? } if SourcePtr^ = #0 then Break else begin { continue comparing, +1 because first character was matched already } SourceMatchPtr := SourcePtr + 1; SearchMatchPtr := PChar(Search) + 1; while (SourceMatchPtr^ = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) do begin Inc(SourceMatchPtr); Inc(SearchMatchPtr); end; { did we find a complete match? } if SearchMatchPtr^ = #0 then begin { append replace to result and move past the search string in source } Move((@Replace[1])^, ResultPtr^, ReplaceLength); Inc(SourcePtr, SearchLength); Inc(ResultPtr, ReplaceLength); { replace all instances or just one? } if not (rfReplaceAll in Flags) then begin { just one, copy until end of source and break out of loop } while SourcePtr^ <> #0 do begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; Break; end; end else begin { copy current character and start over with the next } ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; end; end; { append null terminator, copy into S and reset the string length } ResultPtr^ := #0; S := ResultStr; SetLength(S, StrLen(PChar(S)));end;// case insensitive StrReplaceprocedure StrReplaceCI(var S: AnsiString; Search, Replace: AnsiString; Flags: TReplaceFlags);var ResultStr: string; { result string } SourcePtr: PChar; { pointer into S of character under examination } SourceMatchPtr: PChar; { pointers into S and Search when first character has } SearchMatchPtr: PChar; { been matched and we're probing for a complete match } ResultPtr: PChar; { pointer into Result of character being written } SearchLength, { length of search string } ReplaceLength, { length of replace string } ResultLength: Integer; { length of result string (maximum, worst-case scenario) } C: Char; { first character of search string }begin //if (S = '') or (Search = '') then Exit; Search := UpperCase(Search); { avoid having to call Length() within the loop } SearchLength := Length(Search); ReplaceLength := Length(Replace); { initialize result string to maximum (worst case scenario) length } if Length(Search) >= ReplaceLength then ResultLength := Length(S) else ResultLength := ((Length(S) div Length(Search)) + 1) * Length(Replace); SetLength(ResultStr, ResultLength); { get pointers to begin of source and result } ResultPtr := PChar(ResultStr); SourcePtr := PChar(S); C := Search[1]; { while we haven't reached the end of the string } while True do begin { copy characters until we find the first character of the search string } while (UpCase(SourcePtr^) <> C) and (SourcePtr^ <> #0) do begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; { did we find that first character or did we hit the end of the string? } if SourcePtr^ = #0 then Break else begin { continue comparing, +1 because first character was matched already } SourceMatchPtr := SourcePtr + 1; SearchMatchPtr := PChar(Search) + 1; while (UpCase(SourceMatchPtr^) = SearchMatchPtr^) and (SearchMatchPtr^ <> #0) do begin Inc(SourceMatchPtr); Inc(SearchMatchPtr); end; { did we find a complete match? } if SearchMatchPtr^ = #0 then begin { append replace to result and move past the search string in source } Move((@Replace[1])^, ResultPtr^, ReplaceLength); Inc(SourcePtr, SearchLength); Inc(ResultPtr, ReplaceLength); { replace all instances or just one? } if not (rfReplaceAll in Flags) then begin { just one, copy until end of source and break out of loop } while SourcePtr^ <> #0 do begin ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; Break; end; end else begin { copy current character and start over with the next } ResultPtr^ := SourcePtr^; Inc(ResultPtr); Inc(SourcePtr); end; end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -