grep -E uses some extended ERE syntax, meaning that the quantifier brackets {n,m} (and also ( and ) ) should not be escaped (not in the case of the BRE regular expression).
You need to pass the REG_EXTENDED flag to regcomp , and also, since you cannot use the word boundary, replace the first \b with (^|[^[:alnum:]_]) "equivalent". You do not need to stop \b , since the template has::
const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)";
The part (^|[^[:alnum:]_]) matches either the beginning of the line ( ^ ) or ( | ) a char, except for alphanumeric or underscore.
Full C demo :
#include <stdio.h> #include <stdlib.h> #include <regex.h> int main (void) { int match; int err; regex_t preg; regmatch_t pmatch[4]; size_t nmatch = 4; const char *str_request = "abc: 1234567890@werty.wer.sdfg.net "; const char *str_regex = "(^|[^[:alnum:]_])(abc|def):[0-9]{10}@([A-Za-z0-9].*)"; err = regcomp(&preg, str_regex, REG_EXTENDED); if (err == 0) { match = regexec(&preg, str_request, nmatch, pmatch, 0); nmatch = preg.re_nsub; regfree(&preg); if (match == 0) { printf("\"%.*s\"\n", pmatch[2].rm_eo - pmatch[2].rm_so, &str_request[pmatch[2].rm_so]); printf("\"%.*s\"\n", pmatch[3].rm_eo - pmatch[3].rm_so, &str_request[pmatch[3].rm_so]); } else if (match == REG_NOMATCH) { printf("unmatch\n"); } } return 0; }
source share