c posix регулярное выражение для проверки ввода строки времени ЧЧ: ММ: СС - PullRequest
0 голосов
/ 24 февраля 2012

Относится к Шаблон регулярного выражения для ЧЧ: ММ: строка времени SS Я пытаюсь проверить ввод времени пользователя.

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. Я получаю ошибку неизвестной escape-последовательности\ d '.

что здесь не так?Это лучший способ проверки ввода времени пользователем?Редактировать: Попытка с "^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$", и я не получаю соответствия.Также с

Ответы [ 4 ]

3 голосов
/ 24 февраля 2012

Вы можете попробовать strptime(), например

struct tm t;
char p;

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

if (p == NULL || *p != '\0') {
    abort();
}
1 голос
/ 28 февраля 2012

Механизм регулярных выражений POSIX не поддерживает группы без захвата (?:...). Вместо этого используйте обычные группы:

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

У меня не установлен gcc. Если базовым механизмом регулярных выражений является POSIX BRE вместо POSIX ERE (как я думал), тогда нужен другой синтаксис (поскольку скобки обрабатываются как литералы, если не экранированы, а POSIX BRE не знают квантификатор ?:

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

или, как строка:

"^\\(\\(\\([01]\\{0,1\\}[0-9]|2[0-3]\\):\\)\\{0,1\\}\\([0-5]\\{0,1\\}[0-9]\\):\\)\\{0,1\\}\\([0-5]\\{0,1\\}[0-9]\\)$"
0 голосов
/ 24 февраля 2012

В C \ является escape-символом в строке, вы должны удвоить его, чтобы получить escape-символ в регулярном выражении, т.е. \\.

Попробуйте это:

"^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$"
0 голосов
/ 24 февраля 2012

Потому что, когда вы пишете \, а затем компилятор букв думает, что это специальный символ, такой как \n (символ новой строки) или \t (символ табуляции). И нет символа \d, поэтому вы получаете сообщение об ошибке. Вы должны написать \\d, если вы имеете в виду «цифра». На самом деле вам просто нужно экранировать обратную косую черту (\ - это escape-символ в C, C ++, Java, C # и многих других языках).
Например, это перемешивание "abc\n\\d" на самом деле "abc[enter]\d" в памяти. Поэтому, когда вы вводите \\d в шаблон, на самом деле он сохраняется в памяти как \d, фактически то, что вам нужно.

...