📄 rm_jclstrings.pas.~1~
字号:
{**************************************************************************************************}
{ }
{ Project JEDI Code Library (JCL) }
{ }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
{ License at http://www.mozilla.org/MPL/ }
{ }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
{ and limitations under the License. }
{ }
{ The Original Code is JclStrings.pas. }
{ }
{ The Initial Developer of the Original Code is Marcel van Brakel. }
{ Portions created by Marcel van Brakel are Copyright (C) Marcel van Brakel. All rights reserved. }
{ }
{ Contributor(s): }
{ Alexander Radchenko }
{ Andreas Hausladen }
{ Anthony Steele }
{ Azret Botash }
{ Barry Kelly }
{ Huanlin Tsai }
{ Jack N.A. Bakker }
{ Jean-Fabien Connault }
{ John C Molyneux }
{ Leonard Wennekers }
{ Martin Kimmings }
{ Martin Kubecka }
{ Massimo Maria Ghisalberti }
{ Matthias Thoma (mthoma) }
{ Michael Winter }
{ Nick Hodges }
{ Olivier Sannier }
{ Pelle F. S. Liljendal }
{ Petr Vones }
{ Rik Barker (rikbarker) }
{ Robert Lee }
{ Robert Marquardt }
{ Robert Rossmair (rrossmair) }
{ }
{**************************************************************************************************}
{ }
{ Various character and string routines (searching, testing and transforming) }
{ }
{**************************************************************************************************}
// Last modified: $Date: 2006-01-15 11:10:45 -0800 (Sun, 15 Jan 2006) $
// For history see end of file
unit rm_JclStrings;
{$I rm_jcl.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF MSWINDOWS}
Classes, SysUtils,
{$IFDEF CLR}
System.Text,
{$ELSE}
rm_JclWideStrings,
{$ENDIF CLR}
rm_JclBase;
// Character constants and sets
const
// Misc. often used character definitions
AnsiNull = Char(#0);
AnsiSoh = Char(#1);
AnsiStx = Char(#2);
AnsiEtx = Char(#3);
AnsiEot = Char(#4);
AnsiEnq = Char(#5);
AnsiAck = Char(#6);
AnsiBell = Char(#7);
AnsiBackspace = Char(#8);
AnsiTab = Char(#9);
AnsiLineFeed = rm_JclBase.AnsiLineFeed;
AnsiVerticalTab = Char(#11);
AnsiFormFeed = Char(#12);
AnsiCarriageReturn = rm_JclBase.AnsiCarriageReturn;
AnsiCrLf = rm_JclBase.AnsiCrLf;
AnsiSo = Char(#14);
AnsiSi = Char(#15);
AnsiDle = Char(#16);
AnsiDc1 = Char(#17);
AnsiDc2 = Char(#18);
AnsiDc3 = Char(#19);
AnsiDc4 = Char(#20);
AnsiNak = Char(#21);
AnsiSyn = Char(#22);
AnsiEtb = Char(#23);
AnsiCan = Char(#24);
AnsiEm = Char(#25);
AnsiEndOfFile = Char(#26);
AnsiEscape = Char(#27);
AnsiFs = Char(#28);
AnsiGs = Char(#29);
AnsiRs = Char(#30);
AnsiUs = Char(#31);
AnsiSpace = Char(' ');
AnsiComma = Char(',');
AnsiBackslash = Char('\');
AnsiForwardSlash = Char('/');
AnsiDoubleQuote = Char('"');
AnsiSingleQuote = Char('''');
AnsiLineBreak = rm_JclBase.AnsiLineBreak;
// Misc. character sets
AnsiWhiteSpace = [AnsiTab, AnsiLineFeed, AnsiVerticalTab,
AnsiFormFeed, AnsiCarriageReturn, AnsiSpace];
AnsiSigns = ['-', '+'];
AnsiUppercaseLetters = rm_JclBase.AnsiUppercaseLetters;
AnsiLowercaseLetters = rm_JclBase.AnsiLowercaseLetters;
AnsiLetters = rm_JclBase.AnsiLetters;
AnsiDecDigits = rm_JclBase.AnsiDecDigits;
AnsiOctDigits = rm_JclBase.AnsiOctDigits;
AnsiHexDigits = rm_JclBase.AnsiHexDigits;
AnsiValidIdentifierLetters = rm_JclBase.AnsiValidIdentifierLetters;
const
// CharType return values
C1_UPPER = $0001; // Uppercase
C1_LOWER = $0002; // Lowercase
C1_DIGIT = $0004; // Decimal digits
C1_SPACE = $0008; // Space characters
C1_PUNCT = $0010; // Punctuation
C1_CNTRL = $0020; // Control characters
C1_BLANK = $0040; // Blank characters
C1_XDIGIT = $0080; // Hexadecimal digits
C1_ALPHA = $0100; // Any linguistic character: alphabetic, syllabary, or ideographic
{$IFDEF MSWINDOWS}
{$IFDEF SUPPORTS_EXTSYM}
{$EXTERNALSYM C1_UPPER}
{$EXTERNALSYM C1_LOWER}
{$EXTERNALSYM C1_DIGIT}
{$EXTERNALSYM C1_SPACE}
{$EXTERNALSYM C1_PUNCT}
{$EXTERNALSYM C1_CNTRL}
{$EXTERNALSYM C1_BLANK}
{$EXTERNALSYM C1_XDIGIT}
{$EXTERNALSYM C1_ALPHA}
{$ENDIF SUPPORTS_EXTSYM}
{$ENDIF MSWINDOWS}
// String Test Routines
function StrIsAlpha(const S: string): Boolean;
function StrIsAlphaNum(const S: string): Boolean;
function StrIsAlphaNumUnderscore(const S: string): Boolean;
function StrContainsChars(const S: string; Chars: TSysCharSet; CheckAll: Boolean): Boolean;
function StrConsistsOfNumberChars(const S: string): Boolean;
function StrIsDigit(const S: string): Boolean;
function StrIsSubset(const S: string; const ValidChars: TSysCharSet): Boolean;
function StrSame(const S1, S2: string): Boolean;
// String Transformation Routines
function StrCenter(const S: string; L: Integer; C: Char = ' '): string;
function StrCharPosLower(const S: string; CharPos: Integer): string;
function StrCharPosUpper(const S: string; CharPos: Integer): string;
function StrDoubleQuote(const S: string): string;
function StrEnsureNoPrefix(const Prefix, Text: string): string;
function StrEnsureNoSuffix(const Suffix, Text: string): string;
function StrEnsurePrefix(const Prefix, Text: string): string;
function StrEnsureSuffix(const Suffix, Text: string): string;
function StrEscapedToString(const S: string): string;
function StrLower(const S: string): string;
procedure StrLowerInPlace(var S: string);
{$IFNDEF CLR}
procedure StrLowerBuff(S: PChar);
{$ENDIF ~CLR}
procedure StrMove(var Dest: string; const Source: string; const ToIndex,
FromIndex, Count: Integer);
function StrPadLeft(const S: string; Len: Integer; C: Char = AnsiSpace ): string;
function StrPadRight(const S: string; Len: Integer; C: Char = AnsiSpace ): string;
function StrProper(const S: string): string;
{$IFNDEF CLR}
procedure StrProperBuff(S: PChar);
{$ENDIF ~CLR}
function StrQuote(const S: string; C: Char): string;
function StrRemoveChars(const S: string; const Chars: TSysCharSet): string;
function StrKeepChars(const S: string; const Chars: TSysCharSet): string;
procedure StrReplace(var S: string; const Search, Replace: string; Flags: TReplaceFlags = []);
function StrReplaceChar(const S: string; const Source, Replace: Char): string;
function StrReplaceChars(const S: string; const Chars: TSysCharSet; Replace: Char): string;
function StrReplaceButChars(const S: string; const Chars: TSysCharSet; Replace: Char): string;
function StrRepeat(const S: string; Count: Integer): string;
function StrRepeatLength(const S: string; L: Integer): string;
function StrReverse(const S: string): string;
procedure StrReverseInPlace(var S: string);
function StrSingleQuote(const S: string): string;
function StrSmartCase(const S: string; Delimiters: TSysCharSet): string;
function StrStringToEscaped(const S: string): string;
function StrStripNonNumberChars(const S: string): string;
function StrToHex(const Source: string): string;
function StrTrimCharLeft(const S: string; C: Char): string;
function StrTrimCharsLeft(const S: string; const Chars: TSysCharSet): string;
function StrTrimCharRight(const S: string; C: Char): string;
function StrTrimCharsRight(const S: string; const Chars: TSysCharSet): string;
function StrTrimQuotes(const S: string): string;
function StrUpper(const S: string): string;
procedure StrUpperInPlace(var S: string);
{$IFNDEF CLR}
procedure StrUpperBuff(S: PChar);
{$ENDIF ~CLR}
{$IFDEF WIN32}
function StrOemToAnsi(const S: string): string;
function StrAnsiToOem(const S: string): string;
{$ENDIF WIN32}
{$IFNDEF CLR}
// String Management
procedure StrAddRef(var S: string);
function StrAllocSize(const S: string): Longint;
procedure StrDecRef(var S: string);
function StrLen(S: PChar): Integer;
function StrLength(const S: string): Longint;
function StrRefCount(const S: string): Longint;
{$ENDIF ~CLR}
procedure StrResetLength(var S: string); overload;
{$IFDEF CLR}
procedure StrResetLength(S: StringBuilder); overload;
{$ENDIF CLR}
// String Search and Replace Routines
function StrCharCount(const S: string; C: Char): Integer;
function StrCharsCount(const S: string; Chars: TSysCharSet): Integer;
function StrStrCount(const S, SubS: string): Integer;
function StrCompare(const S1, S2: string): Integer;
function StrCompareRange(const S1, S2: string; const Index, Count: Integer): Integer;
function StrFillChar(const C: Char; Count: Integer): string;
function StrFind(const Substr, S: string; const Index: Integer = 1): Integer;
function StrHasPrefix(const S: string; const Prefixes: array of string): Boolean;
function StrIndex(const S: string; const List: array of string): Integer;
function StrILastPos(const SubStr, S: string): Integer;
function StrIPos(const SubStr, S: string): Integer;
function StrIsOneOf(const S: string; const List: array of string): Boolean;
function StrLastPos(const SubStr, S: string): Integer;
function StrMatch(const Substr, S: string; const Index: Integer = 1): Integer;
function StrMatches(const Substr, S: string; const Index: Integer = 1): Boolean;
function StrNIPos(const S, SubStr: string; N: Integer): Integer;
function StrNPos(const S, SubStr: string; N: Integer): Integer;
function StrPrefixIndex(const S: string; const Prefixes: array of string): Integer;
function StrSearch(const Substr, S: string; const Index: Integer = 1): Integer;
// String Extraction
function StrAfter(const SubStr, S: string): string;
function StrBefore(const SubStr, S: string): string;
function StrBetween(const S: string; const Start, Stop: Char): string;
function StrChopRight(const S: string; N: Integer): string;
function StrLeft(const S: string; Count: Integer): string;
function StrMid(const S: string; Start, Count: Integer): string;
function StrRestOf(const S: string; N: Integer): string;
function StrRight(const S: string; Count: Integer): string;
// Character Test Routines
function CharEqualNoCase(const C1, C2: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsAlpha(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsAlphaNum(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsBlank(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsControl(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsDelete(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsDigit(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsLower(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsNumberChar(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsPrintable(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsPunctuation(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsReturn(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsSpace(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsUpper(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
function CharIsWhiteSpace(const C: Char): Boolean; {$IFDEF CLR} inline; {$ENDIF}
{$IFNDEF CLR}
function CharType(const C: Char): Word;
{$ENDIF ~CLR}
// Character Transformation Routines
function CharHex(const C: Char): Byte;
function CharLower(const C: Char): Char; {$IFDEF CLR} inline; {$ENDIF}
function CharUpper(const C: Char): Char; {$IFDEF CLR} inline; {$ENDIF}
function CharToggleCase(const C: Char): Char;
// Character Search and Replace
function CharPos(const S: string; const C: Char; const Index: Integer = 1): Integer;
function CharLastPos(const S: string; const C: Char; const Index: Integer = 1): Integer;
function CharIPos(const S: string; C: Char; const Index: Integer = 1 ): Integer;
function CharReplace(var S: string; const Search, Replace: Char): Integer;
{$IFNDEF CLR}
// PCharVector
type
PCharVector = ^PChar;
function StringsToPCharVector(var Dest: PCharVector; const Source: TStrings): PCharVector;
function PCharVectorCount(Source: PCharVector): Integer;
procedure PCharVectorToStrings(const Dest: TStrings; Source: PCharVector);
procedure FreePCharVector(var Dest: PCharVector);
// MultiSz Routines
type
PMultiSz = PChar;
PWideMultiSz = PWideChar;
function StringsToMultiSz(var Dest: PMultiSz; const Source: TStrings): PMultiSz;
procedure MultiSzToStrings(const Dest: TStrings; const Source: PMultiSz);
function MultiSzLength(const Source: PMultiSz): Integer;
procedure AllocateMultiSz(var Dest: PMultiSz; Len: Integer);
procedure FreeMultiSz(var Dest: PMultiSz);
function MultiSzDup(const Source: PMultiSz): PMultiSz;
function WideStringsToWideMultiSz(var Dest: PWideMultiSz; const Source: TWideStrings): PWideMultiSz;
procedure WideMultiSzToWideStrings(const Dest: TWideStrings; const Source: PWideMultiSz);
function WideMultiSzLength(const Source: PWideMultiSz): Integer;
procedure AllocateWideMultiSz(var Dest: PWideMultiSz; Len: Integer);
procedure FreeWideMultiSz(var Dest: PWideMultiSz);
function WideMultiSzDup(const Source: PWideMultiSz): PWideMultiSz;
{$ENDIF ~CLR}
// TStrings Manipulation
procedure StrIToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True);
procedure StrToStrings(S, Sep: string; const List: TStrings; const AllowEmptyString: Boolean = True);
function StringsToStr(const List: TStrings; const Sep: string; const AllowEmptyString: Boolean = True): string;
procedure TrimStrings(const List: TStrings; DeleteIfEmpty: Boolean = True );
procedure TrimStringsRight(const List: TStrings; DeleteIfEmpty: Boolean = True);
procedure TrimStringsLeft(const List: TStrings; DeleteIfEmpty: Boolean = True );
function AddStringToStrings(const S: string; Strings: TStrings; const Unique: Boolean): Boolean;
// Miscellaneous
function BooleanToStr(B: Boolean): string;
function FileToString(const FileName: string): AnsiString;
procedure StringToFile(const FileName: string; const Contents: AnsiString);
function StrToken(var S: string; Separator: Char): string;
procedure StrTokens(const S: string; const List: TStrings);
procedure StrTokenToStrings(S: string; Separator: Char; const List: TStrings);
{$IFDEF CLR}
function StrWord(const S: string; var Index: Integer; out Word: string): Boolean;
{$ELSE}
function StrWord(var S: PChar; out Word: string): Boolean;
{$ENDIF CLR}
function StrToFloatSafe(const S: string): Float;
function StrToIntSafe(const S: string): Integer;
procedure StrNormIndex(const StrLen: Integer; var Index: Integer; var Count: Integer); overload;
{$IFDEF CLR}
function ArrayOf(List: TStrings): TDynStringArray; overload;
{$ENDIF CLR}
{$IFDEF COMPILER5} // missing Delphi 5 functions
function TryStrToInt(const S: string; out Value: Integer): Boolean;
function TryStrToInt64(const S: string; out Value: Int64): Boolean;
function TryStrToFloat(const S: string; out Value: Extended): Boolean; overload;
function TryStrToFloat(const S: string; out Value: Double): Boolean; overload;
function TryStrToFloat(const S: string; out Value: Single): Boolean; overload;
function TryStrToCurr(const S: string; out Value: Currency): Boolean;
{$ENDIF COMPILER5}
// Exceptions
type
EJclStringError = EJclError;
implementation
uses
{$IFDEF CLR}
System.Globalization,
{$ENDIF CLR}
{$IFDEF HAS_UNIT_LIBC}
Libc,
{$ENDIF HAS_UNIT_LIBC}
Math, rm_JclResources;
//=== Internal ===============================================================
{$IFNDEF CLR}
type
TAnsiStrRec = packed record
AllocSize: Longint;
RefCount: Longint;
Length: Longint;
end;
const
AnsiStrRecSize = SizeOf(TAnsiStrRec); // size of the string header rec
AnsiCharCount = Ord(High(Char)) + 1; // # of chars in one set
AnsiLoOffset = AnsiCharCount * 0; // offset to lower case chars
AnsiUpOffset = AnsiCharCount * 1; // offset to upper case chars
AnsiReOffset = AnsiCharCount * 2; // offset to reverse case chars
AnsiAlOffset = 12; // offset to AllocSize in StrRec
AnsiRfOffset = 8; // offset to RefCount in StrRec
AnsiLnOffset = 4; // offset to Length in StrRec
AnsiCaseMapSize = AnsiCharCount * 3; // # of chars is a table
var
AnsiCaseMap: array [0..AnsiCaseMapSize - 1] of Char; // case mappings
AnsiCaseMapReady: Boolean = False; // true if case map exists
AnsiCharTypes: array [Char] of Word;
procedure LoadCharTypes;
var
CurrChar: Char;
CurrType: Word;
{$IFDEF CLR}
Category: System.Globalization.UnicodeCategory;
{$ENDIF CLR}
begin
for CurrChar := Low(Char) to High(Char) do
begin
{$IFDEF MSWINDOWS}
GetStringTypeExA(LOCALE_USER_DEFAULT, CT_CTYPE1, @CurrChar, SizeOf(Char), CurrType);
{$DEFINE CHAR_TYPES_INITIALIZED}
{$ENDIF MSWINDOWS}
{$IFDEF LINUX}
CurrType := 0;
if isupper(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_UPPER;
if islower(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_LOWER;
if isdigit(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_DIGIT;
if isspace(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_SPACE;
if ispunct(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_PUNCT;
if iscntrl(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_CNTRL;
if isblank(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_BLANK;
if isxdigit(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_XDIGIT;
if isalpha(Byte(CurrChar)) <> 0 then
CurrType := CurrType or C1_ALPHA;
{$DEFINE CHAR_TYPES_INITIALIZED}
{$ENDIF LINUX}
AnsiCharTypes[CurrChar] := CurrType;
{$IFNDEF CHAR_TYPES_INITIALIZED}
Implement case map initialization here
{$ENDIF ~CHAR_TYPES_INITIALIZED}
end;
end;
procedure LoadCaseMap;
var
CurrChar, UpCaseChar, LoCaseChar, ReCaseChar: Char;
begin
if not AnsiCaseMapReady then
begin
for CurrChar := Low(Char) to High(Char) do
begin
{$IFDEF MSWINDOWS}
LoCaseChar := CurrChar;
UpCaseChar := CurrChar;
Windows.CharLowerBuff(@LoCaseChar, 1);
Windows.CharUpperBuff(@UpCaseChar, 1);
{$DEFINE CASE_MAP_INITIALIZED}
{$ENDIF MSWINDOWS}
{$IFDEF LINUX}
LoCaseChar := Char(tolower(Byte(CurrChar)));
UpCaseChar := Char(toupper(Byte(CurrChar)));
{$DEFINE CASE_MAP_INITIALIZED}
{$ENDIF LINUX}
{$IFNDEF CASE_MAP_INITIALIZED}
Implement case map initialization here
{$ENDIF ~CASE_MAP_INITIALIZED}
if CharIsUpper(CurrChar) then
ReCaseChar := LoCaseChar
else
if CharIsLower(CurrChar) then
ReCaseChar := UpCaseChar
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -