【问题标题】:c posix regex to validate input HH:MM:SS time stringc posix 正则表达式来验证输入 HH:MM:SS 时间字符串
【发布时间】: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;
}
  1. 我收到错误未知转义序列“\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,所以我猜您发布的错误消息不是您当前收到的实际错误消息。你能告诉我们真正的问题吗?

标签: c regex validation time posix


【解决方案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 保存在内存中,这正是您所需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 2020-06-25
      相关资源
      最近更新 更多