Ich habe ein Programm, mit dem der Benutzer eine Maske wie z. B. MM-TT-JJJJ angeben und sie mit einer Zeichenkette vergleichen kann. In der Zeichenkette wird die MM wird als ein Monat angenommen, DD ist der Tag des Monats, und YYYY ist das Jahr. Alles andere muss genau übereinstimmen:
- Zeichenfolge: 31.12.2010 Maske MM-TT-JJJJ: Fail: Muss Schrägstriche und keine Bindestriche verwenden
- Zeichenfolge: 31.12.2010 Maske DD/MM/YYYY: Fehlgeschlagen: Der Monat muss der zweite sein und es gibt keinen Monat 31 .
- Zeichenfolge: 31.12.11 Maske: MM/TD-JJ: Pass: Zeichenfolge stimmt mit Maske überein.
Im Moment verwende ich index
y substr
um den Monat, den Tag und das Jahr herauszufinden, dann verwende ich xor
um eine Maske für alles andere zu erzeugen. Es scheint ein bisschen unelegant, und ich frage mich, ob es eine bessere Möglichkeit, dies zu tun:
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...]
Ich tue dies für ein Datum, eine Uhrzeit (mit HH , MM , SS und A /*AA*), und IP-Adressen in meinem Code.
BTW, habe ich versucht, mit regulären Ausdrücken, um das Datum aus der Zeichenfolge zu ziehen, aber es ist noch chaotischer:
#-----------------------------------------------------------------------
# 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
#
#-----------------------------------------------------------------------
Es ist ein netter Programmiertrick, aber es war ziemlich schwierig, genau zu verstehen, was ich tat, und das würde es für jemand anderen schwierig machen, es zu warten.