Skip to content

Instantly share code, notes, and snippets.

@rexim
Created October 7, 2020 12:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rexim/c6714e2e0d98e703a0a8d4b8ae2299d4 to your computer and use it in GitHub Desktop.
Save rexim/c6714e2e0d98e703a0a8d4b8ae2299d4 to your computer and use it in GitHub Desktop.
PCRE2 C++ example with named capture groups
#define PCRE2_CODE_UNIT_WIDTH 8
#include <stdio.h>
#include <string.h>
#include <pcre2.h>
#define MY_PATTERN "\\[(?<hours>\\d+):(?<minutes>\\d+):(?<seconds>\\d+)(\\.(?<milliseconds>\\d+))?\\] \\<(?<nickname>\\w+)\\> (?<message>.*)"
#define MY_SUBJECT "[0:00:01] <Tsoding> forsenPls forsenPls forsenPls forsenPls forsenPls forsenPls forsenPls forsenPls forsenPls forsenPls"
const char *line_comps[] = {
"hours",
"minutes",
"seconds",
"milliseconds",
"nickname",
"message",
};
const size_t line_comps_count = sizeof(line_comps) / sizeof(line_comps[0]);
int main(int argc, char *argv[])
{
PCRE2_SPTR pattern;
pattern = (PCRE2_SPTR) MY_PATTERN;
printf("Regex to use: %s\n", pattern);
printf("Text to parse: %s\n", MY_SUBJECT);
int errorcode = 0;
PCRE2_SIZE erroroffset = 0;
pcre2_code *re = pcre2_compile(pattern, strlen(MY_PATTERN), 0, &errorcode, &erroroffset, NULL);
if (re == NULL) {
PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, buffer);
exit(1);
}
PCRE2_SPTR subject = (PCRE2_SPTR) MY_SUBJECT; /* the appropriate width (in this case, 8 bits). */
size_t subject_length = strlen(MY_SUBJECT);
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL);
int rc = pcre2_match(
re, /* the compiled pattern */
subject, /* the subject string */
subject_length, /* the length of the subject */
0, /* start at offset 0 in the subject */
0, /* default options */
match_data, /* block for storing the result */
NULL); /* use default match context */
if (rc < 0) {
switch(rc) {
case PCRE2_ERROR_NOMATCH:
printf("No match\n");
break;
default:
printf("Matching error %d\n", rc);
break;
}
exit(1);
}
printf("rc = %d\n", rc);
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
printf("Match succeeded at offset %d\n", (int)ovector[0]);
for (size_t i = 0; i < line_comps_count; ++i) {
int index = pcre2_substring_number_from_name(re, (PCRE2_SPTR) line_comps[i]);
PCRE2_SPTR substring_start = subject + ovector[2*index];
size_t substring_length = ovector[2*index+1] - ovector[2*index];
printf("%s: %.*s\n", line_comps[i], (int)substring_length, (char *)substring_start);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment