| af Martin Elsman og Niels Hallenberg | sidst rettet 15. februar, 2002 |
regexp-kommandoen.Angiv mønstre for
42
42.
.42
42.42
Vink:Dit mønster skal tage højde for to muligheder: (1) tvungen
tal til venstre for . og mulighed for tal til højre. (2)
tvungen tal til højre for . og mulighed for tal til
venstre. Du angiver valgmuligheder med |. Et tvungen tal
kan f.eks. laves med [0-9]+. Et valgfrit tal kan
f.eks. laves med [0-9]*. Punktum er altid valgfri,
dvs. du kan anvende \.? til at matche punktum.
Følgende strenge skal genkendes: "1", "1.", "1.0", ".1",
"1032.343", ".04330" og ".3".
Følgende strenge skal ikke genkendes: "1a2", ".", "32,23",
"a.3" og "to.3".
http:// efterfulgt af en ikke tom sekvens af tegn fra det
engelske alfabet, cifre, ., / og
_.
Følgende strenge skal genkendes: "http://a", "http://4_a"
og "http://a/aa.html".
Følgende strenge skal ikke genkendes: "", "http://",
"http://a€#" og "http://aø.tcl".
regexp-kommandoen
bruges til at teste mønstrene.
I den første del af opgaven skal du konstruere et regexp-mønster
(pattern) til matching af datoer på
formen
hvor hvert bogstav
D, M og Y står for et tal mellem 0 og 9. De
første to cifre udgør dagen i datoen, de næste to cifre udgør måneden
og de sidste fire cifre udgør året. Her er nogle eksempler på strenge
for hvilke regexp-kommandoen
skal returnere 1 (for success) og hvorefter variablerne
dd, mm, og yyyy bliver sat til
de respektive tal:
Bemærk at mønsteret ikke skal sikre at datoen er egentlig eksisterende! Her er nogle eksempler på strenge for hvilke% regexp $date_pattern "24.12.2000" match dd mm yyyy 1 % set dd 24 % set mm 12 % set yyyy 2000 % regexp $date_pattern "12.53.1999" match dd mm yyyy 1 % set dd 12 % set mm 53 % set yyyy 1999
regexp-kommandoen
skal returnere 0 (for fejl):
Det er altså din opgave at konstruere mønsteret i variablen% regexp $date_pattern "24.12.00" match dd mm yyyy 0 % regexp $date_pattern "10.5.1999" match dd mm yyyy 0
date_pattern. Løsningen skal bruges senere i opgaven.
Du skal nu i den resterende del af opgaven konstruere en webservice
hvor en bruger kan indtaste en dato i et form-felt og få svar på
hvilken ugedag datoen falder på. Løsningen skal bestå af to filer
placeret på hug.it.edu i biblioteket
/web/login/www/oevelse5/:
weekday.html:weekday.tcl aktiveres med en
form-variabel, navngivet date, indeholdende den
indtastede dato.
weekday.tcl:weekday.tcl:
# --------------------------------------------------------------------
# Return 1 if year is a leap year, zero otherwise
# --------------------------------------------------------------------
proc date_leap { y } {
return [expr ($y % 4 == 0) && ($y % 100 != 0) || ($y % 400 == 0)]
}
# --------------------------------------------------------------------
# Return the number of leap years since year 0 and before year y
# --------------------------------------------------------------------
proc date_preceeding_leaps { y } {
if { $y == 0 } {
return 0
} else {
incr y -1
return [expr 1 + $y / 4 - $y / 100 + $y / 400]
}
}
# --------------------------------------------------------------------
# Return the number of days in a given month; uses year to deal with
# leap days
# --------------------------------------------------------------------
proc date_days_in_month { year month } {
switch -regexp $month {
^(1|3|5|7|8|10|12)$ { return 31 }
^(4|6|9|11)$ { return 30 }
^2$ { if [date_leap $year] {
return 29
} else {
return 28
}
}
default { return -1 }
}
}
# --------------------------------------------------------------------
# Return 1 if a date is valid, 0 otherwise
# --------------------------------------------------------------------
proc date_ok { dd mm yyyy } {
return [expr ($mm >= 1) && ($mm <= 12) && ($dd >= 1) && ($dd <= [date_days_in_month $yyyy $mm])]
}
# --------------------------------------------------------------------
# Given a date (dd, mm, yyyy), return the number of days since
# 01.01.0000
# --------------------------------------------------------------------
proc date_preceeding_days { dd mm yyyy } {
# days in last month
set days [expr $dd - 1]
# days in preceeding months
incr mm -1
while { $mm >= 1 } {
incr days [date_days_in_month $yyyy $mm]
incr mm -1
}
# days in preceeding years
incr days [expr 365 * $yyyy + [date_preceeding_leaps $yyyy]]
return $days
}
# --------------------------------------------------------------------
# Given a number between 0 and 6, return a weekday, starting with
# Saturday (01.01.0000 was a Saturday!)
# --------------------------------------------------------------------
proc date_pr_day { i } {
switch $i {
0 {return Saturday}
1 {return Sunday}
2 {return Monday}
3 {return Tuesday}
4 {return Wednesday}
5 {return Thursday}
6 {return Friday}
default {return "WRONG DAY"}
}
}
# --------------------------------------------------------------------
# remove leading zeros from a number; fails if the argument is
# not a number.
# --------------------------------------------------------------------
proc remove_leading_zeros { n } {
if { [regexp {^0*([1-9][0-9]*)$} $n match res] == 0 } {
regexp {^0*(0)$} $n match res
}
return $res
}
Efterfølgende i filen weekday.tcl skal du indsætte
nedenstående procedure, hvor du har indsat dit dato-mønster, som du
konstruerede tidligere i opgaven:
# --------------------------------------------------------------------
# Given a date in the form DD.MM.YYYY, return the weekday; if date
# is not valid, return -1
# --------------------------------------------------------------------
proc weekday { date } {
# the date pattern to use
set date_pattern {<==INDSÆT DIT DATO-MØNSTER HER==>}
# return -1 if matching fails
if { ![regexp $date_pattern $date match dd mm yyyy] } {
return -1
}
# remove leading zeros from dd, mm, and yyyy; tcl treats numbers
# with leading zeros as octal numbers!
set dd [remove_leading_zeros $dd]
set mm [remove_leading_zeros $mm]
set yyyy [remove_leading_zeros $yyyy]
# return -1 if date is not valid
if { ![date_ok $dd $mm $yyyy] } {
return -1
}
# calculate the number of preceeding days since 01.01.0000
set preceeding_days [date_preceeding_days $dd $mm $yyyy]
return [date_pr_day [expr $preceeding_days % 7]]
}
Du mangler nu kun tilslut i weekday.tcl filen at indsætte
et kald til set_form_variables proceduren, hvorefter
weekday-proceduren skal kaldes med datoen fra form-feltet
som argument. Indsæt sidst i filen weekday.tcl kode til
at returnere (med ns_return) HTML-kode indeholdende
resultatet af at kalde weekday-proceduren.
Indsæt et link til servicen fra din index.html side på hug.it.edu.
Vejledende løsning:
![]() |
![]() |