2

我需要一个正则表达式,它匹配单个时间值以及格式为 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”。有人可以给我一个提示我做错了什么吗?

提前致谢!

4

5 回答 5

1

您应该添加一个^来指示正则表达式从行首开始匹配。

以下正则表达式应该可以工作。

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

自己试试

于 2012-07-22T16:34:56.510 回答
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
于 2012-07-22T16:41:55.230 回答
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;
    }
}
于 2012-07-22T19:41:45.983 回答
0

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

如果您首先编写一个公共子表达式,然后像子例程一样使用它,您会发现编写正则表达式更清晰、更容易。它还有助于使用/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
于 2012-07-22T23:20:07.017 回答
-1

此正则表达式必须有效:

/^(\d+)(, ?\d+)*$/
于 2012-07-22T17:50:31.260 回答