Recent

Author Topic: [SOLVED] Parsing a small buffer for multiple occurances of a regular expression  (Read 3415 times)

Gizmo

  • Hero Member
  • *****
  • Posts: 831
I am reading file data using TFileStreams in buffers of 1024 bytes (mostly).

I then use TRegExpr to see if a certain reg exp is found in the buffer. If it is, it 'does stuff' with the hit and then moves onto the next 1024 bytes of data and repeats until all the file is read.

Trouble is, sometimes, the buffer can contain the reg expr more than once, but the second (and upwards) occurances of the hit are obviously missed this way.

I am trying to work out how to get my program to "Parse the buffer for the regular expression. If found, do stuff, then check the rest of the buffer before reading the next segment".

The nearest string based function I found is NPos (http://www.freepascal.org/docs-html/rtl/strutils/npos.html) but I not sure if that is what I need - I think it needs to know the N-th number you want in advance.

Bascially, I have so far :

Code: [Select]
function MyFunc(SourceFile:TFileStream): string

var
  Buffer                                           : array [1..1024] of char;
  TotalBytesRead, BytesRead         : Int64; 
  MyRegExpr                                   : TRegExpr;

try
     SourceFile.Position := 0;
      while TotalBytesRead < SourceFile.Size do
      begin 
        BytesRead := SourceFile.Read(Buffer,sizeof(Buffer)); // Read 1024 bytes of data
        inc(TotalBytesRead, BytesRead);   // Keep track of the amount of data read
        // Buffer is then converted to ASCII and non-ASCII content removed and assigned to string variable 's'
       if MyRegExpr.Exec(s) then
         // Do stuff with the hit found in s
         end;
      end; // Go and read the next 1024 bytes
   end; // All data read
finally
  // Free Resources etc
« Last Edit: October 23, 2012, 10:57:13 pm by tedsmith »

TLama

  • Newbie
  • Posts: 2
Re: Parsing a small buffer for multiple occurances of a regular expression
« Reply #1 on: October 23, 2012, 02:21:36 am »
I think you're trying to process all matches in a given string. To do so, you can, as the easiest way use the TRegExpr.ExecNext function. It returns True until there's no next match in the input string executed by a previous TRegExpr.Exec function call. In code it can look like this (this example uses the email regex match):

Code: [Select]
uses
  RegExpr;

procedure TForm1.Button1Click(Sender: TObject);
var
  S: string;
  RegEx: TRegExpr;
begin
  RegEx := TRegExpr.Create;
  try
    S := 'tlama@inbox.com, tlama@email.cz';
    RegEx.Expression := '(\b[a-z0-9._%-]+@[a-z0-9.-]+\.[a-z]{2,4}\b)';

    if RegEx.Exec(S) then
    repeat
      ShowMessage(RegEx.Match[0]);
    until
      not RegEx.ExecNext;

  finally
    RegEx.Free;
  end;
end;
« Last Edit: October 23, 2012, 11:25:40 am by TLama »

Gizmo

  • Hero Member
  • *****
  • Posts: 831
Re: Parsing a small buffer for multiple occurances of a regular expression
« Reply #2 on: October 23, 2012, 10:56:57 pm »
Thanks TLama

So simple...and so obvious! How stupid do I feel now!?


 

TinyPortal © 2005-2018