i want to define a regexp constant in my script at the top and use it later to check the date string's format.
my date string will be defined as
$a="2013-03-20 11:09:30.788";
but it failed. how should i do ?
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=~®EXP1){
print "not"
}else{
print "yes"
}
print "\n";
m operator in Perl is used to match a pattern within the given text. The string passed to m operator can be enclosed within any character which will be used as a delimiter to regular expressions.
The metacharacter \b is an anchor like the caret and the dollar sign. It matches at a position that is called a “word boundary”. This match is zero-length. There are three different positions that qualify as word boundaries: Before the first character in the string, if the first character is a word character.
(?:...) A non-capturing version of regular parentheses. Matches whatever regular expression is inside the parentheses, but the substring matched by the group cannot be retrieved after performing a match or referenced later in the pattern.
print operator in Perl is used to print the values of the expressions in a List passed to it as an argument. Print operator prints whatever is passed to it as an argument whether it be a string, a number, a variable or anything. Double-quotes(“”) are used as a delimiter to this operator.
First, let's look at "/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/";
If you had warnings on, you should have gotten:
Unrecognized escape \d passed through at C:\temp\jj.pl line 7. Unrecognized escape \D passed through at C:\temp\jj.pl line 7. Unrecognized escape \d passed through at C:\temp\jj.pl line 7. …
If you print the value of REGEXP1
, you will get /^d{4}Dd{2}Dd{2}Dd{2}Dd{2}Dd{2}Dd{3}
(*wait, what happened to $/
?). Clearly, that does not look like the pattern you wanted.
Now, you could type "/^\\d{4}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{2}\\D\\d{3}\$/"
and then interpolate that string into a pattern, but that's too much work. Instead, you can define your constant using the regexp quote operator, 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';
There is one more gotcha: \d
and \D
will match more than just [0-9]
and [^0-9]
, respectively. So, instead, you could write your pattern like:
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;
But, you are still left with the question of whether those values are meaningful. If that matters, you can use 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);
Which version of Perl are you using? It works for me in 5.8.8 (but not 5.004) if you change it to this:
use constant REGEXP1 => qr/^\d{4}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{2}\D\d{3}$/;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With