Last active
November 29, 2021 15:57
-
-
Save raoulduke/1babb0592e9062d8b330c57ea08862cb to your computer and use it in GitHub Desktop.
C regex get all matches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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