2012-07-22 34 views
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”。 有人可以给我一个提示我做错了什么?

在此先感谢!

回答

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 
+0

这种格式是'[,hhmm] +',而不是'hhmm [,hhmm] +'。 – dave 2012-07-22 16:47:38

+0

谢谢cdtits,完美的作品!@dave:说实话,我没有完全理解上面的表达式,但我试过了,它也是为hhmm :) – user1542785 2012-07-22 17:53:54

+0

@ user1542785我的意思是以','开头的字符串(如'“,1234”' ) 比赛。 – dave 2012-07-22 19:40:41

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

+0

啊,好吧......听起来逻辑对我:)谢谢! – user1542785 2012-07-22 17:56:12

-1

这个规则表达式必须努力:

/^(\d+)(, ?\d+)*$/ 
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; 
    } 
} 
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