cregex

Pattern match using regex in C


I am trying to match an user input with a certain predefined patterns. Here is the situation:

Lets say the user enters: @myFrined messageToSend, it should match: @[:word:] [:word:].

What I tried for now:

//get line from stdin
size_t len = 0;
size_t input_size;
char *command = NULL;

input_size = getline(&command, &len, stdin);

printf("Read %lu characters\n", input_size);
printf("Input: %s", command);

regex_t regex;

//predefine patterns
char* exit_command = "/exit";
char* login_command = "/login [:word:] [:word:]";
char* privmsg_command = "@[:word:] [:word:]";
char* register_command = "/register [:word:] [:word:]";

//pattern results: 0 match ||| 1 not a match
int pattern_command_exit;
int pattern_command_login;
int pattern_command_privmsg;
int pattern_command_register;

//test the input against the patters
pattern_command_exit = regcomp(&regex, exit_command, 0);
pattern_command_exit = regexec(&regex, command, 0, NULL, 0);

pattern_command_login = regcomp(&regex, login_command, 0);
pattern_command_login = regexec(&regex, command, 0, NULL, 0);

pattern_command_privmsg = regcomp(&regex, privmsg_command, 0);
pattern_command_privmsg = regexec(&regex, command, 0, NULL, 0);

pattern_command_register = regcomp(&regex, register_command, 0);
pattern_command_register = regexec(&regex, command, 0, NULL, 0);

//*******actual results*******// 
printf("/exit: %d\n", pattern_command_exit);
printf("/login: %d\n", pattern_command_login);
printf("/private message: %d\n", pattern_command_privmsg);
printf("/register: %d\n", pattern_command_register);

This is working only for /exit, which makes sense since I did something wrong somewhere.

Any ideas how I can correctly use regexes to match these patterns?


Solution

  • Three problems:

    1. The character class name needs to be enclosed in two brackets on each side, e.g. [[:alpha:]].

    2. Even if the syntax was correct, word is not a valid character class, the only valid character classes are (from the manual page):

      alnum   digit   punct
      alpha   graph   space
      blank   lower   upper
      cntrl   print   xdigit
      
    3. If you want to match multiple characters of the same class, you also need a \+ (which escaped becomes \\+), e.g. "[[:alnum:]]\\+".

    You will have to either choose one from those, or if none suits your needs just use a custom bracket expression, like for example [a-zA-z0-9_-]\\+ to match one or more alphanumeric characters (upper or lower) plus - and _.