У меня есть программа, которая позволяет пользователю указать маску, например MM-DD-YYYY, и сравнить ее со строкой. В строке MM будет считаться месяцем, DD будет днем месяца, а YYYY будет годом. Все остальное должно точно соответствовать:
- Строка: 31.12.2010 Маска MM-ДД-ГГГГ: ошибка: необходимо использовать косую черту, а не тире
- Строка: 31.12.2010 Маска ДД / ММ / ГГГГ: ошибка: месяц должен быть вторым, а месяца нет 31 .
- Строка: 12 / 31-11 Маска: ММ / ДД-ГГ: Пропуск: строка соответствует маске.
Прямо сейчас я использую index
и substr
, чтобы извлечь месяц, день и год, затем я использую 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...]
Я делаю это для даты, времени (используя ЧЧ , ММ , СС и А / * АА *) и 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
#
#-----------------------------------------------------------------------
Это хитрый трюк в программировании, но было довольно сложно понять, что именно я делал, и, следовательно, было бы трудно поддерживать кого-то еще.