6

スクリプトの先頭で正規表現定数を定義し、後でそれを使用して日付文字列の形式を確認したいと考えています。

私の日付文字列は次のように定義されます

$a="2013-03-20 11:09:30.788";

しかし、それは失敗しました。どうすればいいですか?

 use strict;
 use warnings;


 use constant REGEXP1 => "/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/";

 $a="2013-03-20 11:09:30.788";
 if(not $a=~&REGEXP1){
         print "not"

 }else{
         print "yes"

 }
 print "\n";
4

2 に答える 2

9

まず、"/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/";警告がオンになっている場合は、次のようになっているはずです。

C:\temp\jj.pl 行 7 で認識されないエスケープ \d が渡されました。
C:\temp\jj.pl 行 7 で認識されないエスケープ \D が渡されました。
C:\temp\jj.pl 行 7 で認識されないエスケープ \d が渡されました。
…

の値を出力REGEXP1すると、/^d{4}Dd{2}Dd{2}Dd{2}Dd{2}Dd{2}Dd{3}(*待って、どうしたの$/?) が得られます。明らかに、それはあなたが望んでいたパターンのようには見えません。

これで、その文字列を入力して補間してパターンにすることができますが"/^\\d{4}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{3}\$/"、それは大変な作業です。代わりに、正規表現引用演算子qrを使用して定数を定義できます。

#!/usr/bin/env perl

use 5.012;
use strict;
use warnings;

use constant REGEXP1 => qr/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/;

my $s = "2013-03-20 11:09:30.788";

say $s =~ REGEXP1 ? 'yes' : 'no';

もう 1 つ落とし穴があります。 \dandは、それぞれと\Dだけではなく、さらに一致します。したがって、代わりに、次のようにパターンを記述できます。[0-9][^0-9]

use constant REGEXP1 => qr{
    \A
    (?<year>  [0-9]{4} ) -
    (?<month> [0-9]{2} ) -
    (?<day>   [0-9]{2} ) [ ]
    (?<hour>  [0-9]{2} ) :
    (?<min>   [0-9]{2} ) :
    (?<sec>   [0-9]{2} ) [.]
    (?<msec>  [0-9]{3} )
    \z
}x;

しかし、これらの値に意味があるかどうかという疑問が残ります。それが重要な場合は、DateTime::Format::Strptimeを使用できます。

#!/usr/bin/env perl

use 5.012;
use strict;
use warnings;

use DateTime::Format::Strptime;

my $s = "2013-03-20 11:09:30.788";

my $strp = DateTime::Format::Strptime->new(
    pattern => '%Y-%m-%d %H:%M:%S.%3N',
    on_error => 'croak',
);

my $dt = $strp->parse_datetime($s);
say $strp->format_datetime($dt);
于 2013-03-20T04:02:17.767 に答える
3

どのバージョンの Perl を使用していますか? これを次のように変更すると、5.8.8 で動作します (5.004 では動作しません)。

use constant REGEXP1 => qr/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/;
于 2013-03-20T02:29:55.440 に答える