cregexstringgrepstrstr

How can I return pointer to the first regex occurrence in a string in C?


At the moment, I am coding my own grep implementation and I have a problem with -o flag when it is used with regular expressions. The following code works properly for ordinary strings:

void do_o(char *pattern, char *line, flags options) {
  char *copy;
  char *temp;
  long unsigned int i;
  copy = line;
  if (options.v) {
    do_o_v(pattern, line, options);
  } 
  else {
      if (options.i) {
      while (copy && strcasestr(copy, pattern))
      {
        i = 0;
        temp = strcasestr(copy, pattern);
        while (i < strlen(pattern))
        {
          printf("%c", temp[i]);
          i++;
        }
        printf("\n");
        copy = strcasestr(copy, pattern) + strlen(pattern);
      }
    } else {
      while (copy && strstr(copy, pattern))
      {
        
        i = 0;
        temp = strstr(copy, pattern);
        while (i < strlen(pattern))
        {
          printf("%c", temp[i]);
          i++;
        }
        printf("\n");
        copy = strstr(copy, pattern) + strlen(pattern);
      }
    }
  }
}

However, I also need to do the same logic for with RegEx. So, everything I need is some function as strstr() or strcasestr() that will also support regex.

When I search regex examples and search my question on Google, I mainly come across examples with the functions regexec() and regcomp(). However the both return integer, not a pointer as I need. Any ideas how can i get a pointer of the first occurrence in the string?

P.S. I need pure C code


Solution

  • Any ideas how can i get a pointer of the first occurrence in the string?

    regexec() has argument regmatch_t *pmatch, which is a pointer to a data structure containing the start and end index of a match. Using the index, you can find a pointer to the first occurrence.

    Here is some example code, where get_first_match() returns a pointer to the first match in a string (warning: this does not implement any sort of error handling).

    #include <stdio.h>
    #include <regex.h>
    
    char *get_first_match(regex_t *pattern, char *str)
    {
        char *ptr = NULL;
        regmatch_t match;
        if (regexec(pattern, str, 1, &match, 0) != REG_NOMATCH) {
            ptr = &str[match.rm_so];
        }
    
        return ptr;
    }
    
    int main()
    {
        char *string = "Example1, Example2, Example3.";
        regex_t *pattern;
    
        regcomp(pattern, "Example2", 0);
    
        printf("%s\n", get_first_match(pattern, string));
    
        regfree(pattern);
    }
    

    This will print "Example2, Example3." Take a look at the man page for more information.