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(®ex, "^((([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(®ex, inputStr, 0, NULL, 0);
if( !reti )
puts("Match");
else if( reti == REG_NOMATCH )
puts("No match");
else
regerror(reti, ®ex, msgbuf, sizeof(msgbuf));
fprintf(stderr, "Regex match failed: %s\n", msgbuf);
printf("%s is the string\n",inputStr2);
reti = regexec(®ex, inputStr2, 0, NULL, 0);
if( !reti )
puts("Match");
else if( reti == REG_NOMATCH )
puts("No match");
else
regerror(reti, ®ex, 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(®ex);
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:SS
或MM:SS
或SS
?所以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 时间字符串的主要内容,如果未能解决你的问题,请参考以下文章
有人能告诉我dateTimeString的正则表达式如下:“YYYY / MM / DD HH:MM:SS”[关闭]
php中匹配HH:MM:SS时间格式的正则表达式? [复制]