c posix 正则表达式来验证输入 HH:MM:SS 时间字符串

Posted

技术标签:

【中文标题】c posix 正则表达式来验证输入 HH:MM:SS 时间字符串【英文标题】:c posix regex to validate input HH:MM:SS time string 【发布时间】:2012-02-24 09:47:00 【问题描述】:

与Regex pattern for HH:MM:SS time string相关 我正在尝试验证用户时间输入。

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;

    我收到错误未知转义序列“\d”。

这里有什么问题吗?这是验证用户时间输入的最佳方式吗? 编辑: 尝试使用"^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$",我得到了不匹配的结果。 还有

【问题讨论】:

这不处理24:00:00 (midnight at the end of the day) 或23:59:60 (leap second) 的情况。这是假设您只想支持精确到秒精度的时间。 @MichaelKjörling 那你会怎么做呢? 使用strptime(%T) @J.F.Sebastian 很简单。但是你认为上面涉及到 regexec 的使用有什么问题? 您的正则表达式(在编辑后的帖子中)不再包含\d,所以我猜您发布的错误消息不是您当前收到的实际错误消息。你能告诉我们真正的问题吗? 【参考方案1】:

你可以试试strptime(),例如

struct tm t;
char p;

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

if (p == NULL || *p != '\0') 
    abort();

【讨论】:

当 J.F.Sebastian 首先提出建议时,我就是这样做的。【参考方案2】:

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]\\)$"

【讨论】:

您是否知道正则表达式旨在匹配HH:MM:SSMM:SSSS?所以59:59 是一个有效的匹配。如果这符合您的要求,那很好。 对不起,但我仍然没有匹配,我知道正则表达式旨在匹配什么。你有运行代码 gcc 吗?这就是整个程序。 @AdityaGameProgrammer:也许底层的正则表达式引擎只是一个 POSIX BRE?我已经相应地编辑了我的答案。 @AdityaGameProgrammer:我错过了一些东西:? 在 POSIX BRE 中不存在,因此需要将其更改为 \0,1\。这样,您的程序就可以工作,至少对于匹配号而言。 1 - 不知道为什么 ideone 说匹配号失败。 2. +1 我这边也一样 posix gcc version 4.3.2 (Debian 4.3.2-1.1) 。至少这是部分工作。【参考方案3】:

在 C 中,\ 是字符串中的转义字符,您必须将其加倍才能在正则表达式中获取转义字符,即 \\

试试这个:

"^(?:(?:([01]?\\d|2[0-3]):)?([0-5]?\\d):)?([0-5]?\\d)$"

【讨论】:

【参考方案4】:

因为当您编写\ 时,字母编译器会认为它是一个特殊字符,例如\n(换行符)或\t(制表符)。并且没有 \d 符号,这就是您收到错误的原因。如果你的意思是“一个数字”,你应该写\\d。实际上,您只需要转义反斜杠(\ 是 C、C++、Java、C# 和许多其他语言中的转义字符)。 例如这个stirng "abc\n\\d"实际上是内存中的"abc[enter]\d"。因此,当您在模式中设置\\d 时,实际上它作为\d 保存在内存中,这正是您所需要的。

【讨论】:

以上是关于c posix 正则表达式来验证输入 HH:MM:SS 时间字符串的主要内容,如果未能解决你的问题,请参考以下文章

PHP 正则表达式匹配各种 hh:mm:ss 视频持续时间

有人能告诉我dateTimeString的正则表达式如下:“YYYY / MM / DD HH:MM:SS”[关闭]

php中匹配HH:MM:SS时间格式的正则表达式? [复制]

求java正则表达式,格式yyyy-mm-dd hh:mm:ss 24小时制的,月份和日期为个位数的时候前面补零,急求

C语言正则表达式

Java,时间的正则表达式