Regex to get Complete Name in C

Viewed 60

I need to get a client name from Java's log using a C regex.

I have tested this regex Client:\\s[a-zA-Z\\s]+ here and works fine.

But in my C program, dont.

#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
  regex_t preg;

  const char *string =
      "[com.example.app.JavaClass.JavaMethod(JavaClass.java:1)] (Thread-1) - "
      "Client: FirstName MiddleName AnotherName LastName, Wallet: WL01, "
      "Agency: 9999, ID: 06611486123, Ticket: TKR211";
  const char *pattern = "Client:\\s[a-zA-Z\\s]+";

  size_t nmatch = 1;
  regmatch_t pmatch[1];

  regcomp(&preg, pattern, REG_ICASE | REG_EXTENDED);

  int ret = regexec(&preg, string, nmatch, pmatch, 0);

  char *match = calloc(pmatch[0].rm_eo - pmatch[0].rm_so, sizeof(char));
  memcpy(match, &string[pmatch[0].rm_so], pmatch[0].rm_eo - pmatch[0].rm_so);

  printf("ret: %d\n", ret);
  printf("rm_eo0: %d\n", pmatch[0].rm_eo);
  printf("rm_so0: %d\n", pmatch[0].rm_so);

  printf("Match: %s\n", match);

  regfree(&preg);

  return 0;
}

$ gcc -Wall -Wextra -Wwrite-strings reg.c && ./a.out

When I execute this I get this output:

ret: 0
rm_eo0: 87
rm_so0: 70
Match: Client: FirstName

What I'm doing wrong?

1 Answers

You need to replace \s inside the bracket expression with [:space:] POSIX character class:

const char *pattern = "Client:\\s[a-zA-Z[:space:]]+";

See the online demo.

The reason for this behavior is that POSIX regex flavor does not allow shorthand character classes like \s, \w, etc. inside bracket expressions, the [\s] pattern matches a backslash or s char in POSIX ERE (enabled with the REG_EXTENDED flag). POSIX character classes are meant to be used inside bracket expressions and they make up for this shortcoming.

Related