Ошибка RegularExpressions.pas или моя?
Псевдопродолжение темы
Есть регулярное выражение: пример на regex101.com
Там в примере всё отрабатывает нормально, а в коде на Delphi:
unit MyUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, RegularExpressions, StrUtils;
type
THauptForm = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
Function ReplaceCC(Const Match: TMatch): String;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
HauptForm: THauptForm;
FMatchCollection: TMatchCollection;
FReplaceCounter: Integer;
FAltSql: String;
Implementation
{$R *.dfm}
Function THauptForm.ReplaceCC(Const Match: TMatch): String;
Var
Pc: pChar;
P: Integer;
Begin
Result:=FMatchCollection[FReplaceCounter].Value;
//поиск с конца
Pc:=SearchBuf(pChar(Result), Length(Result), Length(Result)-1, Length(Result), 'from ', []);
If Pc=Nil Then P:=0
Else Begin
P:=Pc-pChar(Result)+1;
While Not(IsCharAlphaNumeric(Result[P-1])) Do
Dec(P);
End;
If P>0 Then Begin
Insert(', (TSystem.Get_PrintSettings('+FMatchCollection[FReplaceCounter].Groups[2].Value+'.dbrid)).*', Result, P);
Inc(FReplaceCounter);
End;
End;
Procedure THauptForm.FormCreate(Sender: TObject);
Var
RegEx: TRegEx;
MyEval: TMatchEvaluator;
tStr: TStringList;
Begin
tStr:=TStringList.Create;
tStr.Clear;
tStr.Add('SELECT table1.*, adr1 AS name1, adr2 AS name2, adr3 AS name3,');
tStr.Add('lang1 AS l1,');
tStr.Add('lang_hrtgc_id(belhtrp_mce, current_l()) AS _mengenbezih, lang_artmghrrc_id(belhtrp_mce) AS _mengenisond,');
tStr.Add('lang_hrt_id(belhtrp_mce, current_l()) AS _mengenbezih2, lang_artmghrrc_id(belhtrp_mce) AS _mengenisond2,');
tStr.Add('dbf3g_hrtgc_id(belp_nr, current_l()) AS _artzzzbez,');
tStr.Add('TDlrki.IntToStr(belp_id) AS vhrewter_berz,');
tStr.Add('ks_bks AS belp_ks_bez, er_bez AS belp_konto_bez,');
tStr.Add('CASE WHEN belp_gtyp = ''LFS'' THEN Exists(SELECT true FROM lifschwerg WHERE l_id = belp_id) ELSE FALSE END AS hasCreeeZbg');
tStr.Add('FROM betpos LEFT JOIN ksv ON ks_abt=belp_koslle LEFT JOIN erfdloes ON er_to=belp_ko');
tStr.Add('WHERE belp_id = :betttlegid ORDER BY belp_po');
FAltSql:=tStr.Text;
RegEx:=TRegEx.Create('(?P<onlyselect>\bselect\s*.*?\bfrom\s*+(?:only)?\s*+\S++){0}\bselect\s*(?:(?P>onlyselect)|.)*?\bfrom\s*+(?:only)?\s*+(\S++)', [roIgnoreCase, roSingleLine]);
If RegEx.IsMatch(FAltSql) Then Begin
FReplaceCounter:=0;
FMatchCollection:=RegEx.Matches(FAltSql);
MyEval:=ReplaceCC;
Memo1.Lines.Text:=RegEx.Replace(FAltSql, MyEval);
End;
tStr.Free;
End;
End.
Падает при разборе регулярки ошибкой переполнения стека. В чём причина? Думал эта библиотека не поддерживает рекурсию в выражениях, то если несколько строк при задании входной строки закомментировать, то работает. Но стек действительно полный, так много вызовов не должно происходить по идее
Источник: Stack Overflow на русском