2012-07-22 39 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