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

正規表現は、ターゲット文字列内の任意の場所でパターンを検索することを除いて、基本的には問題ありません。つまり、有効な時刻が1つ含まれている文字列はすべて一致します。文字列アンカーの開始と終了を追加し、文字列全体をパターンに一致させる必要があり^ます$

最初に共通部分式を記述してから、それをサブルーチンのように使用すると、正規表現をより明確かつ簡単にコーディングできるようになります。また、/x修飾子を使用すると、空白を使用して表現をより明確にレイアウトできるようになります。

たとえば、これは単一の時間文字列に一致します

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

そして、メイン式でそれを2回置き換えることができます。

(?: ... )部分文字列を本当にキャプチャしたい場合を除いて、の$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 に答える