123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851 |
- {
- This file is part of the Free Component Library (FCL)
- Copyright (c) 2023 The Free Pascal team
- Delphi-compatible Record based Regular expressions API unit.
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- unit System.RegularExpressions;
- {$mode objfpc}
- {$modeswitch advancedrecords}
- interface
- uses
- {$IFDEF FPC_DOTTEDUNITS}
- System.SysUtils, System.RegularExpressionsCore;
- {$ELSE}
- SysUtils, System.RegularExpressionsCore;
- {$ENDIF}
- const
- MatchGrowDelta = 32;
- type
- TRegExOption = (roNone, roIgnoreCase, roMultiLine, roExplicitCapture,
- roCompiled, roSingleLine, roIgnorePatternSpace, roNotEmpty);
- TRegExOptions = set of TRegExOption;
- TREStringDynArray = Array of TREString;
- IObjectReference = Interface ['{69E6C6D3-764F-4A6F-BC3D-5F4E32A2E4F4}']
- Function GetObject : TObject;
- end;
- { TObjectReference }
- TObjectReference = Class(TInterfacedObject,IObjectReference)
- Private
- FObject : TObject;
- Protected
- Function GetObject : TObject;
- Public
- Constructor Create(aObject : TObject);
- Destructor Destroy; override;
- Property Obj : TObject Read GetObject;
- end;
- { TGroup }
- TGroup = record
- private
- FIndex: Integer;
- FLength: Integer;
- FName: TREString;
- FSuccess: Boolean;
- FValue: TREString;
- public
- constructor Create(const aValue,aName: TREString; aIndex, aLength: Integer; aSuccess: Boolean);
- property Index: Integer read FIndex;
- property Length: Integer read FLength;
- property Success: Boolean read FSuccess;
- property Value: TREString read FValue;
- property Name: TREString read FName;
- end;
- TGroupArray = Array of TGroup;
- TGroupCollectionEnumerator = class;
- { TGroupCollection }
- TGroupCollection = record
- private
- FGroups : TGroupArray;
- function GetCount: Integer;
- function GetItem(const aIndex: Variant): TGroup;
- function IndexOfName(const aName : TREString): Integer;
- public
- constructor Create(const aGroups : TGroupArray);
- function GetEnumerator: TGroupCollectionEnumerator;
- property Count: Integer read GetCount;
- property Item[const Index: Variant]: TGroup read GetItem; default;
- end;
- { TGroupCollectionEnumerator }
- TGroupCollectionEnumerator = class
- private
- FGroups: TGroupCollection;
- FCurrent: Integer;
- public
- constructor Create(const aGroups: TGroupCollection);
- function GetCurrent: TGroup;
- function MoveNext: Boolean;
- property Current: TGroup read GetCurrent;
- end;
- { TMatch }
- PMatch = ^TMatch;
- TMatch = record
- private
- FGroup: TGroup;
- FGroups: TGroupCollection;
- FRegex : IObjectReference;
- FNext: PMatch;
- function GetIndex: Integer;
- function GetLength: Integer;
- function GetSuccess: Boolean;
- function GetValue: TREString;
- procedure SetNext(const aNext: PMatch);
- public
- constructor Create(const aRegex: IObjectReference; const aValue: TREString; aIndex, aLength: Integer; aSuccess: Boolean);
- function NextMatch: TMatch;
- function Result_(const Pattern: TREString): TREString;
- property Groups: TGroupCollection read FGroups;
- property Index: Integer read GetIndex;
- property Length: Integer read GetLength;
- property Success: Boolean read GetSuccess;
- property Value: TREString read GetValue;
- end;
- TMatchArray = array of TMatch;
- TMatchCollectionEnumerator = class;
- { TMatchCollection }
- TMatchCollection = record
- private
- FMatches: TMatchArray;
- function GetCount: Integer;
- function GetItem(Index: Integer): TMatch;
- public
- constructor Create(const aRegex : IObjectReference; const aInput: TREString; aOptions: TRegExOptions; aStartPos: Integer);
- function GetEnumerator: TMatchCollectionEnumerator;
- property Count: Integer read GetCount;
- property Item[Index: Integer]: TMatch read GetItem; default;
- end;
- { TMatchCollectionEnumerator }
- TMatchCollectionEnumerator = class
- private
- FCollection: TMatchCollection;
- FCurrent: Integer;
- public
- constructor Create(const aCollection: TMatchCollection);
- function GetCurrent: TMatch;
- function MoveNext: Boolean;
- property Current: TMatch read GetCurrent;
- end;
- TMatchEvaluator = function(const Match: TMatch): TREString of object;
- { TRegEx }
- TRegEx = record
- private
- FOptions: TRegExOptions;
- FRef: IObjectReference;
- FRegEx: TPerlRegEx;
- public
- constructor Create(const aPattern: TREString; aOptions: TRegExOptions = [roNotEmpty]);
- function IsMatch(const aInput: TREString): Boolean; overload;
- function IsMatch(const aInput: TREString; aStartPos: Integer): Boolean; overload;
- class function IsMatch(const aInput, aPattern: TREString): Boolean;overload; static;
- class function IsMatch(const aInput, aPattern: TREString; aOptions: TRegExOptions): Boolean; overload; static;
- class function Escape(const aString: TREString; aUseWildCards: Boolean = False): TREString; static;
- function Match(const aInput: TREString): TMatch; overload;
- function Match(const aInput: TREString; aStartPos: Integer): TMatch; overload;
- function Match(const aInput: TREString; aStartPos, aLength: Integer): TMatch; overload;
- class function Match(const aInput, aPattern: TREString): TMatch; overload; static;
- class function Match(const aInput, aPattern: TREString; aOptions: TRegExOptions): TMatch; overload; static;
- function Matches(const aInput: TREString): TMatchCollection; overload;
- function Matches(const aInput: TREString; aStartPos: Integer): TMatchCollection; overload;
- class function Matches(const aInput, aPattern: TREString): TMatchCollection; overload; static;
- class function Matches(const aInput, aPattern: TREString; aOptions: TRegExOptions): TMatchCollection; overload; static;
- function Replace(const aInput, aReplacement: TREString): TREString; overload;
- function Replace(const aInput: TREString; aEvaluator: TMatchEvaluator): TREString; overload;
- function Replace(const aInput, aReplacement: TREString; aCount: Integer): TREString; overload;
- function Replace(const aInput: TREString; aEvaluator: TMatchEvaluator; aCount: Integer): TREString; overload;
- class function Replace(const aInput, aPattern, aReplacement: TREString): TREString; overload; static;
- class function Replace(const aInput, aPattern: TREString; aEvaluator: TMatchEvaluator): TREString; overload; static;
- class function Replace(const aInput, aPattern, aReplacement: TREString; aOptions: TRegExOptions): TREString; overload; static;
- class function Replace(const aInput, aPattern: TREString; aEvaluator: TMatchEvaluator; aOptions: TRegExOptions): TREString; overload; static;
- function Split(const aInput: TREString): TREStringDynArray; overload; inline;
- function Split(const aInput: TREString; aCount: Integer): TREStringDynArray; overload; inline;
- function Split(const aInput: TREString; aCount, aStartPos: Integer): TREStringDynArray; overload;
- class function Split(const aInput, aPattern: TREString): TREStringDynArray; overload; static;
- class function Split(const aInput, aPattern: TREString; aOptions: TRegExOptions): TREStringDynArray; overload; static;
- end;
-
- { TRegExHelper }
- TRegExHelper = record helper for TRegEx
- public
- procedure Study(Options: TRegExStudyOptions = []);
- procedure AddRawOptions(const Value: Integer);
- end;
- function RegExOptionsToPCREOptions(Value: TRegExOptions): TPerlRegExOptions;
- implementation
- uses
- {$IFDEF FPC_DOTTEDUNITS}
- System.Classes, System.Variants, System.RegularExpressionsConsts;
- {$ELSE}
- Classes, Variants, System.RegularExpressionsConsts;
- {$ENDIF}
- Type
- { TMatcher }
- TMatcher = Class(TObject)
- FMatchEvaluator: TMatchEvaluator;
- FRef: IObjectReference;
- Constructor Create(AMatchEvaluator: TMatchEvaluator; aRef: IObjectReference);
- procedure ReplaceEvent(Sender: TObject; var ReplaceWith: TREString);
- end;
- Function GetRegEx(aRef : IObjectReference) : TPerlRegEx; inline;
- begin
- Result:=aRef.GetObject as TPerlRegex;
- end;
- function RegExOptionsToPCREOptions(Value: TRegExOptions): TPerlRegExOptions;
- Procedure Add(aFlag : TRegExOption; aOpt : TPerlRegExOption);
- begin
- if aFlag in Value then
- Include(Result,aOpt);
- end;
- begin
- Result := [];
- Add(roIgnoreCase,preCaseLess);
- Add(roMultiLine,preMultiLine);
- Add(roExplicitCapture,preNoAutoCapture);
- Add(roSingleLine,preSingleLine);
- Add(roIgnorePatternSpace,preExtended);
- end;
- { TMatcher }
- constructor TMatcher.Create(AMatchEvaluator: TMatchEvaluator; aRef: IObjectReference);
- begin
- FMatchEvaluator:=AMatchEvaluator;
- FRef:=aRef;
- end;
- procedure TMatcher.ReplaceEvent(Sender: TObject; var ReplaceWith: TREString);
- var
- M: TMatch;
- RE : TPerlRegEx;
- begin
- if Assigned(FMatchEvaluator) then
- begin
- RE:=Sender as TPerlRegEx;
- M:=TMatch.Create(FRef,RE.MatchedText,RE.MatchedOffset,Re.MatchedLength,True);
- ReplaceWith:=FMatchEvaluator(M);
- end;
- end;
- { TObjectReference }
- function TObjectReference.GetObject: TObject;
- begin
- Result:=FObject;
- end;
- constructor TObjectReference.Create(aObject: TObject);
- begin
- FObject:=aObject;
- end;
- destructor TObjectReference.Destroy;
- begin
- FreeAndNil(FObject);
- inherited Destroy;
- end;
- { TGroup }
- constructor TGroup.Create(const aValue, aName: TREString; aIndex, aLength: Integer; aSuccess: Boolean);
- begin
- FValue:=aValue;
- FIndex:=aIndex;
- FLength:=aLength;
- FSuccess:=aSuccess;
- FName:=aName;
- end;
- { TGroupCollectionEnumerator }
- constructor TGroupCollectionEnumerator.Create(const aGroups: TGroupCollection);
- begin
- FGroups:=aGroups;
- FCurrent:=-1;
- end;
- function TGroupCollectionEnumerator.GetCurrent: TGroup;
- begin
- Result:=FGroups.FGroups[FCurrent];
- end;
- function TGroupCollectionEnumerator.MoveNext: Boolean;
- begin
- Result:=FCurrent<Length(FGroups.FGroups)-1;
- if Result then
- Inc(FCurrent);
- end;
- { TMatch }
- function TMatch.GetIndex: Integer;
- begin
- Result:=FGroup.Index;
- end;
- function TMatch.GetLength: Integer;
- begin
- Result:=FGroup.Length;
- end;
- function TMatch.GetSuccess: Boolean;
- begin
- Result:=FGroup.Success;
- end;
- function TMatch.GetValue: TREString;
- begin
- Result:=FGRoup.Value;
- end;
- procedure TMatch.SetNext(const aNext: PMatch);
- begin
- FRegex:=Nil;
- FNext:=aNext;
- end;
- constructor TMatch.Create(const aRegex: IObjectReference; const aValue: TREString; aIndex, aLength: Integer; aSuccess: Boolean);
- var
- N : TREStringDynArray;
- G : TGroupArray;
- RE : TPerlRegEx;
- i,idx : Integer;
- GN : TREString;
- begin
- G:=Default(TGroupArray);
- N:=Default(TREStringDynArray);
- FRegex:=aRegex;
- FGroup:=TGroup.Create(aValue,'',aIndex,aLength,aSuccess);
- if Success then
- begin
- RE:=GetRegEx(FRegEx);
- SetLength(N,RE.GroupCount+1);
- For I:=0 to RE.NameCount-1 do
- begin
- GN:=RE.Names[i];
- Idx:=RE.NamedGroup(GN);
- if Idx<>-1 then
- N[Idx]:=GN;
- end;
- SetLength(G,RE.GroupCount+1);
- For I:=0 to RE.GroupCount do
- G[i]:=TGroup.Create(RE.Groups[I],N[i],RE.GroupOffsets[i],RE.GroupLengths[I],aSuccess);
- end;
- FGroups:=TGroupCollection.Create(G);
- end;
- function TMatch.NextMatch: TMatch;
- var
- RE : TPerlRegEx;
- begin
- if Assigned(FRegex) then
- begin
- RE:=GetRegEx(FRegex);
- if RE.MatchAgain then
- Result:=TMatch.Create(FRegex,RE.MatchedText,RE.MatchedOffset,RE.MatchedLength,True)
- else
- Result:=TMatch.Create(FRegex,'',0,0,False);
- end
- else if Assigned(FNext) then
- Result:=FNext^
- else
- Result:=TMatch.Create(FRegex,'',0,0,False);
- end;
- function TMatch.Result_(const Pattern: TREString): TREString;
- var
- RE: TPerlRegEx;
- begin
- RE:=GetRegEx(FRegex);
- RE.Replacement:=Pattern;
- Result:=RE.ComputeReplacement;
- end;
- { TMatchCollection }
- constructor TMatchCollection.Create(const aRegex: IObjectReference; const aInput: TREString; aOptions: TRegExOptions;
- aStartPos: Integer);
- var
- Found: Boolean;
- Len : Integer;
- RE: TPerlRegEx;
- begin
- RE:=GetRegEx(aRegex);
- RE.Subject:=aInput;
- RE.Options:=RegExOptionsToPCREOptions(AOptions);
- RE.Start:=aStartPos;
- Len:=0;
- SetLength(FMatches,0);
- Found:=RE.Match;
- while Found do
- begin
- if Len>=Length(FMatches) then
- SetLength(FMatches,Length(FMatches)+MatchGrowDelta);
- FMatches[Len]:=TMatch.Create(aRegex,RE.MatchedText,RE.MatchedOffset,RE.MatchedLength,Found);
- if Len>0 then
- FMatches[Len-1].SetNext(@FMatches[Len]);
- Found:=RE.MatchAgain;
- Inc(Len);
- end;
- FMatches[Len-1].SetNext(Nil);
- if Len<Length(FMatches) then
- SetLength(FMatches,Len);
- end;
- function TMatchCollection.GetCount: Integer;
- begin
- Result:=Length(FMatches);
- end;
- function TMatchCollection.GetItem(Index: Integer): TMatch;
- begin
- Result:=FMatches[Index];
- end;
- function TMatchCollection.GetEnumerator: TMatchCollectionEnumerator;
- begin
- Result:=TMatchCollectionEnumerator.Create(Self);
- end;
- { TMatchCollectionEnumerator }
- constructor TMatchCollectionEnumerator.Create(const aCollection: TMatchCollection);
- begin
- FCollection:=aCollection;
- FCurrent:=-1;
- end;
- function TMatchCollectionEnumerator.GetCurrent: TMatch;
- begin
- Result:=FCollection.FMatches[FCurrent];
- end;
- function TMatchCollectionEnumerator.MoveNext: Boolean;
- begin
- Result:=FCurrent<Length(FCollection.FMatches)-1;
- If Result then
- Inc(FCurrent);
- end;
- { TRegEx }
- constructor TRegEx.Create(const aPattern: TREString; aOptions: TRegExOptions);
- begin
- FRegEx:=TPerlRegEx.Create;
- Foptions:=aOPtions;
- FRegex.Options:=RegExOptionsToPCREOptions(aOptions);
- FRegex.RegEx:=aPattern;
- FRef:=TObjectReference.Create(FRegex);
- end;
- function TRegEx.IsMatch(const aInput: TREString): Boolean;
- begin
- Result:=IsMatch(aInput,1);
- end;
- function TRegEx.IsMatch(const aInput: TREString; aStartPos: Integer): Boolean;
- begin
- FRegex.Subject:=aInput;
- FRegex.Start:=aStartPos;
- Result:=FRegex.Match;
- end;
- class function TRegEx.IsMatch(const aInput, aPattern: TREString): Boolean;
- begin
- Result:=IsMatch(aInput,aPattern,[roNotEmpty]);
- end;
- class function TRegEx.IsMatch(const aInput, aPattern: TREString; aOptions: TRegExOptions): Boolean;
- var
- RE : TRegEx;
- begin
- RE:=TRegex.Create(aPattern,aOptions);
- Result:=RE.IsMatch(aInput);
- end;
- class function TRegEx.Escape(const aString: TREString; aUseWildCards: Boolean): TREString;
- function esc(const s : TREString; c : char; rep : string) : string;
- begin
- Result:=StringReplace(s,'\'+c,rep,[rfReplaceAll]);
- Result:=StringReplace(Result,Rep+rep,'\'+c,[rfReplaceAll]);
- end;
- begin
- Result:=TPerlRegEx.EscapeRegExChars(aString);
- Result:=StringReplace(Result,#13#10,'\r\n',[rfReplaceAll]);
- if Not aUseWildCards then
- exit;
- Result:=Esc(Result,'?','(.)');
- Result:=Esc(Result,'*','(.*)');
- end;
- function TRegEx.Match(const aInput: TREString): TMatch;
- begin
- Result:=Match(aInput,1,Length(aInput));
- end;
- function TRegEx.Match(const aInput: TREString; aStartPos: Integer): TMatch;
- begin
- Result:=Match(aInput,aStartPos,Length(aInput));
- end;
- function TRegEx.Match(const aInput: TREString; aStartPos, aLength: Integer): TMatch;
- var
- Found: Boolean;
- L,O : Integer;
- S : TREString;
- begin
- L:=0;
- O:=0;
- S:='';
- With FRegEx do
- begin
- Subject:=aInput;
- FRegex.Start:=aStartPos;
- FRegex.Stop:=aStartPos+aLength-1;
- Found:=Match;
- if Found then
- begin
- S:=MatchedText;
- O:=MatchedOffset;
- L:=MatchedLength;
- end;
- end;
- Result:=TMatch.Create(FRef,S,O,L,Found);
- end;
- class function TRegEx.Match(const aInput, aPattern: TREString): TMatch;
- var
- RE : TRegEx;
- begin
- RE:=TRegex.Create(aPattern);
- Result:=RE.Match(aInput);
- end;
- class function TRegEx.Match(const aInput, aPattern: TREString; aOptions: TRegExOptions): TMatch;
- var
- RE : TRegEx;
- begin
- RE:=TRegex.Create(aPattern,aOptions);
- Result:=RE.Match(aInput);
- end;
- function TRegEx.Matches(const aInput: TREString): TMatchCollection;
- begin
- Result:=TMatchCollection.Create(FRef,aInput,FOptions,1);
- end;
- function TRegEx.Matches(const aInput: TREString; aStartPos: Integer): TMatchCollection;
- begin
- Result:=TMatchCollection.Create(FRef,aInput,FOptions,aStartPos);
- end;
- class function TRegEx.Matches(const aInput, aPattern: TREString): TMatchCollection;
- var
- RE: TRegEx;
- begin
- RE:=TRegEx.Create(aPattern);
- Result:=RE.Matches(aInput);
- end;
- class function TRegEx.Matches(const aInput, aPattern: TREString; aOptions: TRegExOptions): TMatchCollection;
- var
- RE: TRegEx;
- begin
- RE:=TRegEx.Create(aPattern,aOptions);
- Result:=RE.Matches(aInput);
- end;
- function TRegEx.Replace(const aInput, aReplacement: TREString): TREString;
- begin
- FRegEx.Subject:=aInput;
- FRegEx.Replacement:=aReplacement;
- FRegEx.ReplaceAll;
- Result:=FRegEx.Subject;
- end;
- function TRegEx.Replace(const aInput: TREString; aEvaluator: TMatchEvaluator): TREString;
- var
- M : TMatcher;
- begin
- FRegEx.Subject:=aInput;
- M:=TMatcher.Create(aEvaluator,FRef);
- try
- FRegEx.OnReplace:[email protected];
- FRegEx.ReplaceAll;
- Result := FRegEx.Subject;
- finally
- M.Free;
- end;
- end;
- function TRegEx.Replace(const aInput, aReplacement: TREString; aCount: Integer): TREString;
- var
- I: Integer;
- begin
- if aCount<0 then
- Exit(Replace(aInput,aReplacement));
- I:=0;
- FRegEx.Subject:=aInput;
- FRegEx.Replacement:=aReplacement;
- if FRegEx.Match then
- repeat
- Inc(I);
- FRegEx.Replace;
- until (not FRegEx.MatchAgain) or (I>=aCount);
- Result:=FRegEx.Subject;
- end;
- function TRegEx.Replace(const aInput: TREString; aEvaluator: TMatchEvaluator; aCount: Integer): TREString;
- var
- M : TMatcher;
- I : integer;
- begin
- FRegEx.Subject:=aInput;
- M:=TMatcher.Create(aEvaluator,FRef);
- try
- I:=0;
- FRegEx.Subject:=aInput;
- FRegEx.OnReplace:[email protected];
- if FRegEx.Match then
- repeat
- Inc(I);
- FRegEx.Replace;
- until (not FRegEx.MatchAgain) or (I>=aCount);
- Result:=FRegEx.Subject;
- finally
- M.Free;
- end;
- end;
- class function TRegEx.Replace(const aInput, aPattern, aReplacement: TREString): TREString;
- var
- RE : TRegex;
- begin
- RE:=TRegex.Create(aPattern);
- Result:=RE.Replace(aInput,aReplacement);
- end;
- class function TRegEx.Replace(const aInput, aPattern: TREString; aEvaluator: TMatchEvaluator): TREString;
- begin
- Result:=Replace(aInput,aPattern,aEvaluator,[roNotEmpty]);
- end;
- class function TRegEx.Replace(const aInput, aPattern, aReplacement: TREString; aOptions: TRegExOptions): TREString;
- var
- RE : TRegex;
- begin
- RE:=TRegex.Create(aPattern,aOptions);
- Result:=RE.Replace(aInput,aReplacement);
- end;
- class function TRegEx.Replace(const aInput, aPattern: TREString; aEvaluator: TMatchEvaluator; aOptions: TRegExOptions): TREString;
- var
- RE: TRegEx;
- begin
- RE:=TRegEx.Create(aPattern,aOptions);
- Result:=RE.Replace(aInput,aEvaluator);
- end;
- function TRegEx.Split(const aInput: TREString): TREStringDynArray;
- begin
- Result:=Split(aInput,0,1);
- end;
- function TRegEx.Split(const aInput: TREString; aCount: Integer): TREStringDynArray;
- begin
- Result:=Split(aInput,aCount,1);
- end;
- function TRegEx.Split(const aInput: TREString; aCount, aStartPos: Integer): TREStringDynArray;
- var
- L: TStrings;
- begin
- Result:=Default(TREStringDynArray);
- if aInput='' then
- exit;
- FRegEx.Subject:=aInput;
- Result:=FRegEx.SplitCapture(aCount,aStartPos);
- end;
- class function TRegEx.Split(const aInput, aPattern: TREString): TREStringDynArray;
- var
- RE: TRegEx;
- begin
- RE:=TRegEx.Create(aPattern);
- Result:= RE.Split(aInput);
- end;
- class function TRegEx.Split(const aInput, aPattern: TREString; aOptions: TRegExOptions): TREStringDynArray;
- var
- RE: TRegEx;
- begin
- RE:=TRegEx.Create(aPattern,aOptions);
- Result:=RE.Split(aInput);
- end;
- { TRegExHelper }
- procedure TRegExHelper.Study(Options: TRegExStudyOptions);
- begin
- end;
- procedure TRegExHelper.AddRawOptions(const Value: Integer);
- begin
- end;
- function TGroupCollection.GetCount: Integer;
- begin
- Result:=Length(FGroups);
- end;
- function TGroupCollection.GetItem(const aIndex: Variant): TGroup;
- var
- Idx: Integer;
- IdxIsName : Boolean;
- begin
- IdxIsName:=False;
- Idx:=-1;
- case VarType(aIndex) of
- varByte,
- varWord,
- varLongWord,
- varQWord,
- varSmallint,
- varShortInt,
- varInteger,
- varInt64:
- Idx:=aIndex;
- varString,
- varUString,
- varOleStr:
- begin
- Idx:=IndexOfName(TREString(aIndex));
- idxIsName:=True;
- end
- else
- raise ERegularExpressionError.Create(SRegExInvalidIndexType);
- end;
- if (Idx>=0) and (Idx<Length(FGroups)) then
- Result:=FGroups[Idx]
- else if (Idx=-1) and (IdxIsName) then
- raise ERegularExpressionError.CreateFmt(SRegExInvalidGroupName,[TREString(aIndex)])
- else
- raise ERegularExpressionError.CreateFmt(SRegExIndexOutOfBounds,[Idx]);
- end;
- function TGroupCollection.IndexOfName(const aName: TREString): Integer;
- begin
- Result:=Length(FGroups)-1;
- While (Result>=0) and (FGroups[Result].Name<>'') and Not SameText(aName,FGroups[Result].Name) do
- Dec(Result);
- end;
- constructor TGroupCollection.Create(const aGroups: TGroupArray);
- begin
- FGroups:=aGroups;
- end;
- function TGroupCollection.GetEnumerator: TGroupCollectionEnumerator;
- begin
- Result:=TGroupCollectionEnumerator.Create(Self);
- end;
- end.
|