Skip to content

Instantly share code, notes, and snippets.

@raoulduke
Last active November 29, 2021 15:57
Show Gist options
  • Save raoulduke/1babb0592e9062d8b330c57ea08862cb to your computer and use it in GitHub Desktop.
Save raoulduke/1babb0592e9062d8b330c57ea08862cb to your computer and use it in GitHub Desktop.
C regex get all matches
#include <stdio.h>
#include <string.h>
#include <regex.h>
#define TEST_REGEX "^.*\\/([a-zA-Z_.]*)\\.log : [A-Z]{3} [0-9]{2}\\/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{6} .* : (.*)$"
#define MAX_REGEX_MATCHES 5
#define MAX_STRING_SIZE 1000
#define MAX_ERR_LENGTH 50
/**
* Test regex against string. Requires 2D char array large enough to store found matches.
*
* @param source
* @param pattern
* @param matches
* @return int - Number of matches found
*/
int getRegExMatches(char *source, const char *pattern, char matches[][MAX_STRING_SIZE]) {
int err = 0, numMatches = 0, numGroups = 0;
char errMsg[MAX_ERR_LENGTH];
regex_t myRegEx;
if ((err = regcomp(&myRegEx, pattern, REG_EXTENDED)) != 0) {
regerror(err, &myRegEx, errMsg, MAX_ERR_LENGTH);
printf("Error compiling regular expression '%s': %s", pattern, errMsg);
return 0;
}
// re_nsub contains number of groups (possible matches) in the compiled regex
// the first element of the array (index 0) contains the string that matched the entire
// regular expression, then comes the matching groups, so we must +1 to account for this
numGroups = myRegEx.re_nsub + 1;
regmatch_t rm[numGroups];
// if there are matches:
// rm[0] = full match (this will be discarded)
// rm[1] = group 1 match
// rm[2] = group 2 match, etc...
if ((err = regexec(&myRegEx, source, numGroups, rm, 0)) == 0) {
for (unsigned int i = 1; i <= myRegEx.re_nsub; i++) {
if (rm[i].rm_so == -1) {
break; // no more matches
}
int len = rm[i].rm_eo - rm[i].rm_so;
memcpy(matches[i-1], (source + rm[i].rm_so), len);
matches[i-1][len] = '\0';
printf("Match %u: [%s]\n", i, matches[i-1]);
numMatches++;
}
} else if (err != REG_NOMATCH) {
regerror(err, &myRegEx, errMsg, MAX_ERR_LENGTH);
printf("Error executing regular expression '%s': %s", pattern, errMsg);
regfree(&myRegEx);
return 0;
}
regfree(&myRegEx);
return numMatches;
}
int main() {
char matches[MAX_REGEX_MATCHES][MAX_STRING_SIZE];
char testSource[MAX_STRING_SIZE];
strcpy(testSource, "/var/log/myTestApp.log : ERR 02/18 17:05:14.872780 matt : This is an important log entry.");
getRegExMatches(testSource, TEST_REGEX, matches);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment