tags:

views:

107

answers:

2

Hi,

I would like to specify the regular expression during run-time, not compile-time. So that is why pcre falls out. Do you know C/c++ regular expression library that can parse streams and can recognise relatively complex regular expression such as .+?

Thanks.

+5  A: 

AFAIK boost::regex should know how to work with streams and it supports perl regular expressions

Artyom
I found no streams... but it can accept bidirectional iterators
Aftershock
If you have a recent compiler that provide TR1 libraries, then you have std::(tr1::)regex that is the standard version of boost::regex.
Klaim
+1  A: 

Well, there is PCRE.

Minimal grep implemented with pcre (note that the expression to search for is supplied on the command line at run time):

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include "pcre.h"
#define OVECCOUNT 30    /* should be a multiple of 3 */

/* only needed if your libc doesn't include it! */
#include "getline.c" 

int main(int argc, char**argv){
  char *res;
  char *fname;
  const char *error;
  int erroroffset;
  pcre *re=NULL;

  /* Grab the search expression from the first command line argument */
  if (--argc) {
    res=(++argv)[0];
    re=pcre_compile(res,0,&error,&erroroffset,NULL);
    if (re==NULL) /* compilation failed, bomb out */ exit(1);
  }

  /* All further command line arguments are files to grep in */
  while (--argc) {
    FILE*f=NULL;
    fname=(++argv)[0];

    if (f=fopen(fname,"r")) {
      char *line=NULL;
      size_t l=0;
      while (-1 != getline(&line,&l,f)) {
    int ovector[OVECCOUNT];
    if ( pcre_exec(re,NULL,line,l,0,0,ovector,OVECCOUNT) > 0 ) {
      printf("%s",line);
    }

    free(line);
    line = NULL; l=0;
      }

      fclose(f);
    }
  }
  free(re);
  return 0;
}

Run it:

$ ./pcregrep char pcregrep.c
int main(int argc, char**argv){
  char *res;
  char *fname;
  const char *error;
      char *line=NULL;
dmckee
this is not good. This is not going to match a pattern that spans lines
Aftershock
That is why pcre is not a solution , it does not support streams.
Aftershock
@Aftershock: this bog-simple, sample code is an implementation of *grep*, of course it is not going to span lines. If you want to use pcre to find patters spanning lines you will have to read the data into a buffer such that it includes the newlines.
dmckee