c posix regex to validate input HH:MM:SS time stri

2019-06-09 23:32发布

Related to Regex pattern for HH:MM:SS time string I am trying to validate user time input.

int main(int argc, char *argv[]){
        regex_t regex;
        int reti;
        char msgbuf[100];
        char inputStr2[100]="12:34:04";
        char inputStr[100]="12:34";

/* Compile regular expression */
        reti = regcomp(&regex, "^((([01]?[0-9]|2[0-3]):)?([0-5]?[0-9]):)?([0-5]?[0-9])$", 0);
        if( reti ){
        fprintf(stderr, "Could not compile regex\n");
        }

/* Execute regular expression */
           printf("%s is the string\n",inputStr);
        reti = regexec(&regex, inputStr, 0, NULL, 0);
        if( !reti ){
                puts("Match");
        }
        else if( reti == REG_NOMATCH ){
                puts("No match");
        }
        else{
                regerror(reti, &regex, msgbuf, sizeof(msgbuf));
                fprintf(stderr, "Regex match failed: %s\n", msgbuf);
        }
         printf("%s is the string\n",inputStr2);
        reti = regexec(&regex, inputStr2, 0, NULL, 0);
        if( !reti ){
                puts("Match");
        }
        else if( reti == REG_NOMATCH ){
                puts("No match");
        }
        else{
                regerror(reti, &regex, msgbuf, sizeof(msgbuf));
                fprintf(stderr, "Regex match failed: %s\n", msgbuf);
        }
/* Free compiled regular expression if you want to use the regex_t again */
    regfree(&regex);

        return 0;
}
  1. i get the error unknown escape sequence '\d'.

whats wrong here? Is this the best way to go about validating user time input?. Edit: Tried with "^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$" and i get a no match. Also with

4条回答
贪生不怕死
2楼-- · 2019-06-10 00:06

Because when you write \ and then a letter compiler thinks it's a special character like \n (new line symbol) or \t (tab symbol). And there is no \d symbol that's why you're getting an error. You should write \\d if you mean "a digit". Actually you just need to escape the backslash (\ is the escape character in C, C++, Java, C# and many other languages).
For example this stirng "abc\n\\d" actually is "abc[enter]\d" in memory. So when you right \\d in pattern in fact it's kept in memory as \d, actually what you need.

查看更多
干净又极端
3楼-- · 2019-06-10 00:10

In C, \ is an escape character in a string, you have to double it to get the escape character in a regex ie \\.

Try this:

"^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$"
查看更多
你好瞎i
4楼-- · 2019-06-10 00:24

You could try strptime(), for example

struct tm t;
char p;

p = strptime(inputStr, "%H:%M:%S", &t);

if (p == NULL || *p != '\0') {
    abort();
}
查看更多
小情绪 Triste *
5楼-- · 2019-06-10 00:24

A POSIX regular expression engine does not support non-capturing groups (?:...). Use normal groups instead:

^((([01]?[0-9]|2[0-3]):)?([0-5]?[0-9]):)?([0-5]?[0-9])$

I don't have gcc installed. If the underlying regex engine is a POSIX BRE instead of a POSIX ERE (as I thought), then a different syntax is needed (because parentheses are treated as literals unless escaped, and POSIX BREs don't know the ? quantifier:

^\(\(\([01]\{0,1\}[0-9]|2[0-3]\):\)\{0,1\}\([0-5]\{0,1\}[0-9]\):\)\{0,1\}\([0-5]\{0,1\}[0-9]\)$

or, as a string:

"^\\(\\(\\([01]\\{0,1\\}[0-9]|2[0-3]\\):\\)\\{0,1\\}\\([0-5]\\{0,1\\}[0-9]\\):\\)\\{0,1\\}\\([0-5]\\{0,1\\}[0-9]\\)$"
查看更多
登录 后发表回答