mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 21:39:49 +02:00
MG: regular expressions for search
git-svn-id: trunk@327 -
This commit is contained in:
parent
229fdb1bee
commit
1f8bda0727
@ -128,7 +128,8 @@ const
|
||||
|
||||
type
|
||||
TSynSearchOption = (ssoMatchCase, ssoWholeWord, ssoBackwards,
|
||||
ssoEntireScope, ssoSelectedOnly, ssoReplace, ssoReplaceAll, ssoPrompt);
|
||||
ssoEntireScope, ssoSelectedOnly, ssoReplace, ssoReplaceAll, ssoPrompt
|
||||
{$IFDEF SYN_LAZARUS}, ssoRegExpr, ssoRegExprMultiLine{$ENDIF});
|
||||
TSynSearchOptions = set of TSynSearchOption;
|
||||
|
||||
TSynReplaceAction = (raCancel, raSkip, raReplace, raReplaceAll);
|
||||
@ -5777,8 +5778,12 @@ begin
|
||||
fTSearch.Sensitive := ssoMatchCase in AOptions;
|
||||
fTSearch.Whole := ssoWholeWord in AOptions;
|
||||
fTSearch.Pattern := ASearch;
|
||||
fTSearch.RegularExpressions := ssoRegExpr in AOptions;
|
||||
fTSearch.RegExprSingleLine := not (ssoRegExprMultiLine in AOptions);
|
||||
// search while the current search position is inside of the search range
|
||||
{$IFNDEF SYN_LAZARUS}
|
||||
nSearchLen := Length(ASearch);
|
||||
{$ENDIF}
|
||||
nReplaceLen := Length(AReplace);
|
||||
if bReplaceAll then IncPaintLock;
|
||||
try
|
||||
@ -5788,6 +5793,9 @@ begin
|
||||
// Operate on all results in this line.
|
||||
while nInLine > 0 do begin
|
||||
nFound := fTSearch.Results[n];
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
nSearchLen := fTSearch.ResultLengths[n];
|
||||
{$ENDIF}
|
||||
if bBackward then Dec(n) else Inc(n);
|
||||
Dec(nInLine);
|
||||
// Is the search result entirely in the search range?
|
||||
|
@ -42,7 +42,8 @@ unit SynEditSearch;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes;
|
||||
Classes
|
||||
{$IFDEF SYN_LAZARUS}, RegExpr{$ENDIF};
|
||||
|
||||
procedure MakeCompTable(Sensitive: boolean);
|
||||
procedure MakeDelimiterTable;
|
||||
@ -63,6 +64,16 @@ type
|
||||
fWhole: Boolean;
|
||||
fResults: TList;
|
||||
fShiftInitialized: boolean;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
FoundLen: integer;
|
||||
RegExprEngine : TRegExprEngine;
|
||||
fRegExpr: Boolean;
|
||||
fRegExprFlags: TRegExprFlags;
|
||||
fResultLens: TList;
|
||||
fRegExprSingleLine: boolean;
|
||||
function GetResultLen(Index: integer): integer;
|
||||
procedure SetRegExpr(const NewValue: boolean);
|
||||
{$ENDIF}
|
||||
function GetFinished: Boolean;
|
||||
function GetResult(Index: integer): integer;
|
||||
function GetResultCount: integer;
|
||||
@ -85,6 +96,12 @@ type
|
||||
property ResultCount: integer read GetResultCount;
|
||||
property Sensitive: Boolean read fSensitive write SetSensitive;
|
||||
property Whole: Boolean read fWhole write fWhole;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
property RegularExpressions: Boolean read fRegExpr write SetRegExpr;
|
||||
property ResultLengths[Index: integer]: integer read GetResultLen;
|
||||
property RegExprSingleLine: Boolean
|
||||
read fRegExprSingleLine write fRegExprSingleLine;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -102,12 +119,6 @@ var
|
||||
CompTable: array[#0..#255] of Byte;
|
||||
DelimTable: array[#0..#255] of boolean;
|
||||
|
||||
constructor TSynEditSearch.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
fResults := TList.Create;
|
||||
end;
|
||||
|
||||
procedure MakeCompTable(Sensitive: Boolean);
|
||||
var
|
||||
I: Char;
|
||||
@ -134,6 +145,18 @@ begin
|
||||
for c := #0 to #255 do DelimTable[c] := not IsCharAlphaNumeric(c);
|
||||
end;
|
||||
|
||||
constructor TSynEditSearch.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
fResults := TList.Create;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
fRegExpr:=false;
|
||||
fResultLens := TList.Create;
|
||||
fRegExprSingleLine:=true;
|
||||
FoundLen:=0;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{ TSynEditSearch }
|
||||
|
||||
function TSynEditSearch.GetFinished: Boolean;
|
||||
@ -200,43 +223,64 @@ var
|
||||
J: PChar;
|
||||
begin
|
||||
Result := 0;
|
||||
inc(Run, PatLen);
|
||||
while Run < TheEnd do
|
||||
begin
|
||||
if CompTable[Pat[Patlen]] <> CompTable[Run^] then
|
||||
inc(Run, Shift[CompTable[(Run + 1)^]])
|
||||
else
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if not fRegExpr then begin
|
||||
{$ENDIF}
|
||||
inc(Run, PatLen);
|
||||
FoundLen:=PatLen;
|
||||
while Run < TheEnd do
|
||||
begin
|
||||
J := Run - PatLen + 1;
|
||||
I := 1;
|
||||
while CompTable[Pat[I]] = CompTable[J^] do
|
||||
if CompTable[Pat[Patlen]] <> CompTable[Run^] then
|
||||
inc(Run, Shift[CompTable[(Run + 1)^]])
|
||||
else
|
||||
begin
|
||||
if I = PatLen then
|
||||
J := Run - PatLen + 1;
|
||||
I := 1;
|
||||
while CompTable[Pat[I]] = CompTable[J^] do
|
||||
begin
|
||||
Case fWhole of
|
||||
True: if not TestWholeWord then break;
|
||||
if I = PatLen then
|
||||
begin
|
||||
Case fWhole of
|
||||
True: if not TestWholeWord then break;
|
||||
end;
|
||||
inc(fCount);
|
||||
Result := Run - Origin - Patlen + 2;
|
||||
exit;
|
||||
end;
|
||||
inc(fCount);
|
||||
Result := Run - Origin - Patlen + 2;
|
||||
exit;
|
||||
inc(I);
|
||||
inc(J);
|
||||
end;
|
||||
inc(I);
|
||||
inc(J);
|
||||
end;
|
||||
{begin} //mh 2000-08-29
|
||||
// inc(Run, Look_At + Shift[CompTable[(Run + Look_at)^]] - 1);
|
||||
Inc(Run, Look_At);
|
||||
if Run >= TheEnd then
|
||||
break;
|
||||
Inc(Run, Shift[CompTable[Run^]] - 1);
|
||||
// inc(Run, Look_At + Shift[CompTable[(Run + Look_at)^]] - 1);
|
||||
Inc(Run, Look_At);
|
||||
if Run >= TheEnd then
|
||||
break;
|
||||
Inc(Run, Shift[CompTable[Run^]] - 1);
|
||||
{end} //mh 2000-08-29
|
||||
end;
|
||||
end;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
end else begin
|
||||
// regular expressions
|
||||
inc(Run);
|
||||
if not RegExprPos(RegExprEngine,Run,Result,FoundLen) then begin
|
||||
Run:=TheEnd;
|
||||
Result:=0;
|
||||
end else begin
|
||||
inc(Run,Result);
|
||||
Result:=Run-Origin+1;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
destructor TSynEditSearch.Destroy;
|
||||
begin
|
||||
fResults.Free;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
DestroyRegExprEngine(RegExprEngine);
|
||||
fResultLens.Free;
|
||||
{$ENDIF}
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -252,10 +296,15 @@ end;
|
||||
procedure TSynEditSearch.SetSensitive(const Value: Boolean);
|
||||
begin
|
||||
if fSensitive <> Value then begin
|
||||
writeln('A');
|
||||
fSensitive := Value;
|
||||
MakeCompTable(Value);
|
||||
fShiftInitialized := FALSE;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fSensitive then
|
||||
Exclude(fRegExprFlags,REF_CaseInsensitive)
|
||||
else
|
||||
Include(fRegExprFlags,REF_CaseInsensitive);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -267,10 +316,16 @@ begin
|
||||
InitShiftTable;
|
||||
// never shrink Capacity
|
||||
fResults.Count := 0;
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fRegExpr then fResultLens.Count := 0;
|
||||
{$ENDIF}
|
||||
Found := FindFirst(NewText);
|
||||
while Found > 0 do
|
||||
begin
|
||||
fResults.Add(pointer(Found));
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fRegExpr then fResultLens.Add(pointer(FoundLen));
|
||||
{$ENDIF}
|
||||
Found := Next;
|
||||
end;
|
||||
Result := fResults.Count;
|
||||
@ -280,6 +335,24 @@ function TSynEditSearch.FindFirst(const NewText: string): Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
fTextLen := Length(NewText);
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
if fRegExpr then begin
|
||||
DestroyRegExprEngine(RegExprEngine);
|
||||
if fSensitive then
|
||||
Exclude(fRegExprFlags,REF_CaseInsensitive)
|
||||
else
|
||||
Include(fRegExprFlags,REF_CaseInsensitive);
|
||||
if fRegExprSingleLine then begin
|
||||
Include(fRegExprFlags,REF_SingleLine);
|
||||
Exclude(fRegExprFlags,REF_MultiLine);
|
||||
end else begin
|
||||
Exclude(fRegExprFlags,REF_SingleLine);
|
||||
Include(fRegExprFlags,REF_MultiLine);
|
||||
end;
|
||||
RegExprEngine:=GenerateRegExprEngine(PChar(Pat+#0),fRegExprFlags);
|
||||
PatLen:=length(Pat);
|
||||
end;
|
||||
{$ENDIF}
|
||||
if fTextLen >= PatLen then
|
||||
begin
|
||||
Origin := PChar(NewText);
|
||||
@ -289,9 +362,27 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
function TSynEditSearch.GetResultLen(Index: integer): integer;
|
||||
begin
|
||||
if (Index>=0) and (Index<fResultLens.Count) then
|
||||
Result:=Integer(fResultLens[Index])
|
||||
else
|
||||
Result:=FoundLen;
|
||||
end;
|
||||
|
||||
procedure TSynEditSearch.SetRegExpr(const NewValue: boolean);
|
||||
begin
|
||||
if NewValue=fRegExpr then exit;
|
||||
fRegExpr:=NewValue;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
initialization
|
||||
CompTableSensitive := True; // force the table initialization
|
||||
MakeCompTable(False);
|
||||
MakeDelimiterTable;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -175,7 +175,6 @@ begin
|
||||
Width:=135;
|
||||
Height:=17;
|
||||
Caption:='Regular Expressions';
|
||||
Enabled:=false;
|
||||
Show;
|
||||
end;
|
||||
|
||||
@ -323,6 +322,7 @@ procedure TLazFindReplaceDialog.SetOptions(NewOptions:TSynSearchOptions);
|
||||
begin
|
||||
CaseSensitiveCheckBox.Checked:=ssoMatchCase in NewOptions;
|
||||
WholeWordsOnlyCheckBox.Checked:=ssoWholeWord in NewOptions;
|
||||
RegularExpressionsCheckBox.Checked:=ssoRegExpr in NewOptions;
|
||||
PromptOnReplaceCheckBox.Checked:=ssoPrompt in NewOptions;
|
||||
if ssoEntireScope in NewOptions
|
||||
then OriginRadioGroup.ItemIndex:=1
|
||||
@ -351,6 +351,7 @@ begin
|
||||
Result:=[];
|
||||
if CaseSensitiveCheckBox.Checked then Include(Result,ssoMatchCase);
|
||||
if WholeWordsOnlyCheckBox.Checked then Include(Result,ssoWholeWord);
|
||||
if RegularExpressionsCheckBox.Checked then Include(Result,ssoRegExpr);
|
||||
if PromptOnReplaceCheckBox.Checked then Include(Result,ssoPrompt);
|
||||
if OriginRadioGroup.ItemIndex=1 then Include(Result,ssoEntireScope);
|
||||
if ScopeRadioGroup.ItemIndex=1 then include(Result,ssoSelectedOnly);
|
||||
|
Loading…
Reference in New Issue
Block a user