Recent

Author Topic: TRegExpr fork from A.Torgashin - added named groups, lookahead, lookbehind  (Read 1587 times)

AlexTP

  • Hero Member
  • *****
  • Posts: 2365
    • UVviewsoft
Pls help me to test my fork.
I added some tests (in test_fpc project) but more tests is good.

https://github.com/andgineer/TRegExpr/issues/177
https://github.com/andgineer/TRegExpr/issues/178

Repo
https://github.com/Alexey-T/TRegExpr
« Last Edit: August 03, 2020, 10:10:34 pm by Alextp »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
hello,
i haven't seen   :o  in your repository, an example to display result for  named groups. Is it the function  MatchIndexfromName that must be used to do this ?  like that for example ?   :-[
Code: Pascal  [Select][+][-]
  1. program test_tregexpr_jp;
  2. uses classes, SysUtils,
  3. regexpr {$IFDEF FPC} in '../src/regexpr.pas'{$ENDIF};
  4. const
  5.   exptest: string =  'Artist,Album,ReleaseDate' + LineEnding +
  6.                      'Pink Floyd,The Wall,1979-11-30' + LineEnding +
  7.                      'Spandau Ballet,True,1983-02-28' + LineEnding +
  8.                      'Queen,Jazz,1978-11-10';
  9. var
  10.   R:TRegExpr;
  11. begin
  12.   R := TRegExpr.Create;
  13.   try
  14.       R.Expression:= '(?P<date>' + // group matching the whole date
  15.                      '(?P<year>\d{4})-' + // YYYY year
  16.                      '(?P<month>\d{2})-' + // MM month
  17.                      '(?P<day>\d{2}))';// DD day
  18.       if R.Exec(exptest) then
  19.         begin
  20.          repeat
  21.            WriteLn('date: ' + R.Match[R.MatchIndexfromName('date')]);
  22.            WriteLn('day: ' + R.Match[R.MatchIndexfromName('day')]);
  23.            WriteLn('month: ' + R.Match[R.MatchIndexfromName('month')]);
  24.            WriteLn('year: ' + R.Match[R.MatchIndexfromName('year')]);
  25.            Writeln('============================');
  26.          until not R.ExecNext;
  27.         end;
  28.   finally
  29.     R.Free;
  30.     Readln();
  31.   end;
  32. end.

Result :
Quote
date: 1979-11-30
day: 30
month: 11
year: 1979
============================
date: 1983-02-28
day: 28
month: 02
year: 1983
============================
date: 1978-11-10
day: 10
month: 11
year: 1978
============================

Friendly, J.P
« Last Edit: August 04, 2020, 07:33:49 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

AlexTP

  • Hero Member
  • *****
  • Posts: 2365
    • UVviewsoft
Yes, like this, so you found how to do it?
But you must check that MatchIndexFromIname got n >=0.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
hello,
to simplify the reading of named group, maybe you can add a property to your TRegExpr(MatchGroup for example) in your regexpr.pas like that :

Code: Pascal  [Select][+][-]
  1. function GetMatchGroup(GroupName: RegExprString): RegExprString;  
  2. // ...
  3. property MatchGroup[GroupName: RegExprString]: RegExprString read GetMatchGroup;
  4. // ...
  5. function TRegExpr.GetMatchGroup(GroupName: RegExprString): RegExprString;
  6. var Idx: Integer;
  7. begin
  8.   Result := '';
  9.   Idx := Self.MatchIndexFromName(GroupName);
  10.   if (Idx >= 0) and (endp[Idx] > startp[Idx]) then
  11.     SetString(Result, startp[Idx], endp[Idx] - startp[Idx]);
  12. end; { of function TRegExpr.GetMatchGroup  }
  13.  

use of the new property :
Code: Pascal  [Select][+][-]
  1. program test_tregexpr_jp;
  2. uses classes, SysUtils,
  3. regexpr {$IFDEF FPC} in '../src/regexpr.pas'{$ENDIF};
  4. const
  5.   exptest: string =  'Artist,Album,ReleaseDate' + LineEnding +
  6.                      'Pink Floyd,The Wall,1979-11-30' + LineEnding +
  7.                      'Spandau Ballet,True,1983-02-28' + LineEnding +
  8.                      'Queen,Jazz,1978-11-10';
  9. var
  10.   R:TRegExpr;
  11. begin
  12.   R := TRegExpr.Create;
  13.   try
  14.       Writeln('Named groups Test');
  15.       R.Expression:= '(?P<date>' + // group matching the whole date
  16.                      '(?P<year>\d{4})-' + // YYYY year
  17.                      '(?P<month>\d{2})-' + // MM month
  18.                      '(?P<day>\d{2}))';// DD day
  19.  
  20.       if R.Exec(exptest) then
  21.         begin
  22.          repeat
  23.            WriteLn('date: ' + R.MatchGroup['date']);
  24.            WriteLn('day: ' + R.MatchGroup['day']);
  25.            WriteLn('month: ' + R.MatchGroup['month']);
  26.            WriteLn('year: ' + R.MatchGroup['year']);
  27.            Writeln('============================');
  28.          until not R.ExecNext;
  29.         end;
  30.       Writeln('LookAhead Test');
  31.       R.Expression:= '\d+(?=€)';
  32.       // look for digits, but match only if followed by €
  33.       if R.Exec('1 turkey costs 30€')then Writeln('Result: ' + R.Match[0]);
  34.       Writeln('============================');
  35.       Writeln('LookBehind Test');
  36.       R.Expression:= '(?<=\$)\d+';
  37.       // look for digits, but only if there’s $ before them.
  38.       if R.Exec('1 turkey costs $30') then Writeln('Result: ' + R.Match[0]);
  39.       Writeln('============================');
  40.   finally
  41.     R.Free;
  42.     Readln();
  43.   end;
  44. end.  
i have added a simple  test lookahead  and a simple test lookbehind  in my  test program.
Result :
Quote
Named groups Test
date: 1979-11-30
day: 30
month: 11
year: 1979
============================
date: 1983-02-28
day: 28
month: 02
year: 1983
============================
date: 1978-11-10
day: 10
month: 11
year: 1978
============================
LookAhead Test
Result: 30
============================
LookBehind Test
Result: 30
============================

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

AlexTP

  • Hero Member
  • *****
  • Posts: 2365
    • UVviewsoft
    function MatchFromName(const AName: RegExprString): RegExprString;

It is little better (why to have [] ?) will add it.
Tkx for testing!

 

TinyPortal © 2005-2018