在C中使用正则表达式进行模式匹配

问题描述

我正在尝试将用户输入与某些预定义模式进行匹配。情况如下:

假设用户输入:@myFrined messagetoSend,它应该匹配:@[:word:] [:word:]

我现在尝试的内容

//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,NULL,0);

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

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

pattern_command_register = regcomp(&regex,register_command,0);
pattern_command_register = regexec(&regex,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);

这仅适用于/exit,这是有道理的,因为我在某处做错了事。

有什么想法可以正确使用正则表达式来匹配这些模式吗?

解决方法

三个问题:

  1. 字符类名称需要用两边的方括号括起来,例如[[:alpha:]]

  2. 即使语法正确,word也不是有效的字符类,唯一有效的字符类是(来自the manual page):

    alnum   digit   punct
    alpha   graph   space
    blank   lower   upper
    cntrl   print   xdigit
    
  3. 如果要匹配同一类别的多个字符,则还需要\+(转义为\\+),例如"[[:alnum:]]\\+"

您将不得不从中选择一个,或者如果没有一个适合您的需求,则只需使用自定义的括号表达式,例如[a-zA-z0-9_-]\\+来匹配一个或多个字母数字字符(大写或小写)加{{1 }}和-