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}$/";如果你有警告,你应该得到:

无法识别的转义 \d 在 C:\temp\jj.pl 第 7 行通过。
无法识别的转义 \D 在 C:\temp\jj.pl 第 7 行通过。
无法识别的转义 \d 在 C:\temp\jj.pl 第 7 行通过。
…

如果你打印 的值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';

还有一个陷阱:\d\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 回答