正则表达式验证时间值或时间值列表

时间:2012-07-22 16:21:23

标签: regex perl

我需要一个正则表达式,它匹配单个时间值以及hhmm [,hhmm]格式的时间值列表,例如:

“1245”或“0056,1034,2355”

我对正则表达式不太好..我认为这样做会:

(([0-1][0-9])|(2[0-3]))[0-5][0-9](,[ \t]*(([0-1][0-9])|(2[0-3]))[0-5][0-9])*

正确验证单个时间值,但如果我尝试按时间列表,则接受逗号后面的每个数字。它也匹配“1235,4711”。 有人能给我一个暗示我做错了吗?

提前致谢!

5 个答案:

答案 0 :(得分:1)

您应添加^以指示正则表达式与行的匹配。

以下正则表达式应该有效。

^([01][0-9]|2[0-3])[0-5][0-9](,\s*([01][0-9]|2[0-3])[0-5][0-9])*$

Try it yourself

答案 1 :(得分:1)

$pat = qr/(?:2[0-3]|[01][0-9])[0-5][0-9]/;
while (<DATA>) {
    if (/^$pat(,\s*$pat)*$/) {
        print;
    }
}

__DATA__
1245
0056, 1034,2355
1034,2455

答案 2 :(得分:0)

在我看来,这是更具可读性的正则表达式,它应该可以工作。

while( <DATA> ) {
    if( /
         ^(
            (
                ((0|1)\d)|(2[0-3]) #regex for hour (the first number may be 0, 1, or 2
                                   #if 0 or 1, the second number can be from 0 to 9
                                   #if 2, the second number can be from 0 to 3                 
            )
            [0-5]\d                #regex for minutes (the first number 
                                   #can be from 0 to 5, second from 0 to 9)
          )
          (
            ,\s*                   #comma required 
                                   #the separator may be, or may not be
            (
                ((0|1)\d)|(2[0-3])
            )
            [0-5]\d
          )*$
        /x ) {
        print;
    }
}

答案 3 :(得分:0)

你的正则表达式基本上没问题,只是它在目标字符串中查找 where 模式。这意味着包含单个有效时间的任何字符串都将匹配。您必须添加字符串锚^$的开头和结尾,以强制整个字符串与模式匹配。

如果您首先编写一个公共子表达式然后像子例程一样使用它,您会发现编写正则表达式更清晰,更容易。它还有助于使用/x修饰符,以便您可以使用空格更清晰地布置表达式。

例如,这匹配单个时间字符串

/ ( [0-1][0-9] | 2[0-3] ) [0-5][0-9] /x

你可以继续在主表达中替换两次。

除非你真的想要将子字符串捕获到(?: ... )$1等,否则最好使用非捕获括号,例如$2

看看这个程序,看看你的想法

use strict;
use warnings;

my $time = qr/(?: (?: [0-1][0-9] | 2[0-3] ) [0-5][0-9] ) /x;

while (<DATA>) {
  print if /^ $time (?: ,[ \t]* $time )* $/x;
}
__DATA__
1245
0056, 1034,2355
1235, 4711
0000,1111

<强>输出

1245
0056, 1034,2355
0000,1111

答案 4 :(得分:-1)

此正则表达式必须有效:

/^(\d+)(, ?\d+)*$/