Last active
March 27, 2023 01:03
-
-
Save hbobenicio/5a71d4c536d4d36a19a9e839cd8096fd to your computer and use it in GitHub Desktop.
Posix Regex: Using capture groups to replace missing positive lookaheads
This file contains hidden or 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 <stdlib.h> | |
#include <regex.h> | |
#include <sys/types.h> | |
#include <assert.h> | |
static void regex_must_compile(regex_t* regex, const char* pattern, int flags); | |
int main() { | |
const char* input = " \t a b c /* foo bar\nkk"; | |
printf("input:\n\"%s\"\n\n", input); | |
regex_t r = {0}; | |
regex_must_compile(&r, "^(.*?)(/\\*)", REG_EXTENDED); | |
const size_t num_capture_groups = 2; | |
const size_t nmatches = num_capture_groups + 1; | |
regmatch_t* matches = calloc(nmatches, sizeof(regmatch_t)); | |
assert(matches); | |
if (regexec(&r, input, nmatches, matches, 0) == REG_NOMATCH) { | |
puts("no match"); | |
free(matches); | |
regfree(&r); | |
return 1; | |
} | |
puts("match!"); | |
for (size_t i = 0; i < nmatches; i++) { | |
regoff_t start = matches[i].rm_so; | |
regoff_t end = matches[i].rm_eo; | |
if (end <= start) { | |
continue; | |
} | |
printf("match #%zu: (%02d, %02d):\t\"", i, start, end); | |
for (regoff_t offset = start; offset < end; offset++) { | |
putchar(input[offset]); | |
} | |
puts("\""); | |
} | |
free(matches); | |
regfree(&r); | |
return 0; | |
} | |
static void regex_must_compile(regex_t* regex, const char* pattern, int flags) | |
{ | |
int rc = regcomp(regex, pattern, flags); | |
if (rc != 0) { | |
// When we call regerror with 0, 0 as last parameters, it returns the error msg size | |
// (already considering the '\0') | |
const size_t error_msg_size = regerror(rc, regex, 0, 0); | |
char* error_msg = calloc(error_msg_size, sizeof(char)); | |
if (!error_msg) { | |
fprintf(stderr, "error: regex: compilation failed. pattern=\"%s\"\n", pattern); | |
exit(EXIT_FAILURE); | |
} | |
// We call it once again, now with the error_msg buffer to be set | |
regerror(rc, regex, error_msg, error_msg_size); | |
fprintf(stderr, "error: regex: compilation failed: %s. pattern=\"%s\"\n", error_msg, pattern); | |
free(error_msg); | |
exit(EXIT_FAILURE); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment