Skip to content

Instantly share code, notes, and snippets.

@hbobenicio
Last active March 27, 2023 01:03
Show Gist options
  • Save hbobenicio/5a71d4c536d4d36a19a9e839cd8096fd to your computer and use it in GitHub Desktop.
Save hbobenicio/5a71d4c536d4d36a19a9e839cd8096fd to your computer and use it in GitHub Desktop.
Posix Regex: Using capture groups to replace missing positive lookaheads
#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