我有一个程序允许用户指定一个掩码,如 MM-DD-YYYY,并将其与字符串进行比较。在字符串中,MM将被假定为一个月,DD将是该月的某一天,而 YYYY 将是年。其他一切都必须完全匹配:
- 字符串:12/31/2010 掩码 MM-DD-YYYY:失败:必须使用斜杠而不是破折号
- 字符串:12/31/2010 掩码 DD/MM/YYYY:失败:月份必须是第二个并且没有月份31。
- 字符串:12/31-11 掩码:MM/DD-YY:通过:字符串匹配掩码。
现在,我使用index
andsubstr
提取月、日和年,然后我使用xor
为其他所有内容生成蒙版。这似乎有点不雅,我想知道是否有更好的方法来做到这一点:
my $self = shift;
my $date = shift;
my $format = $self->Format();
my $month;
my $year;
my $day;
my $monthIndex;
my $yearIndex;
my $dayIndex;
#
# Pull out Month, Day, and Year
#
if (($monthIndex = index($format, "MM")) != -1) {
$month = substr($date, $monthIndex, 2);
}
if (($dayIndex = index($format, "DD")) != -1) {
$day = substr($date, $dayIndex, 2);
}
if (($yearIndex = index($format, "YYYY")) != -1) {
$year = substr($date, $yearIndex, 4);
}
elsif (($yearIndex = index($format, "YY")) != -1) {
$year = substr($date, $yearIndex, 2);
if ($year < 50) {
$year += 2000;
}
else {
$year += 1900;
}
}
#
# Validate the Rest of Format
#
(my $restOfFormat = $format) =~ s/[MDY]/./g; #Month Day and Year can be anything
if ($date !~ /^$restOfFormat$/) {
return; #Does not match format
}
[...More Stuff before I return a true value...]
我在我的代码中为日期、时间(使用HH、MM、SS和A /*AA*)和 IP 地址执行此操作。
顺便说一句,我尝试使用正则表达式从字符串中提取日期,但它更加混乱:
#-----------------------------------------------------------------------
# FIND MONTH
#
my $mask = "M" x length($format); #All M's the length of format string
my $monthMask = ($format ^ $mask); #Bytes w/ "M" will be "NULL"
$monthMask =~ s/\x00/\xFF/g; #Change Null bytes to "FF"
$monthMask =~ s/[^\xFF]/\x00/g; #Null out other bytes
#
# ####Mask created! Apply mask to Date String
#
$month = ($monthMask & $date); #Nulls or Month Value
$month =~ s/\x00//g; #Remove Null bytes from string
#
#-----------------------------------------------------------------------
这是一个巧妙的编程技巧,但很难准确理解我在做什么,因此其他人很难维护。