29. marts 2011 - 10:36Der er
8 kommentarer og 1 løsning
Formatering af telefonnumre
Hej, Jeg arbejder på et script som skal løbe en masse telefon numre igennem, og skrive numeret i et pænt format. F.eks. skal den skrive nummret 004512345678 som +45 12 34 56 78 Dette er nemt nok, da danske numre altid skrives på denne måde. Men hvordan gør jeg med udenlandske numre? F.eks. Engelske, Tyske, Polske, Hollandske, Svenske.
Er der nogen som tidligere har lavet et sådan script, eller bare kan hjælpe mig med nogle formaterings regler for de forskellige lande.
hvis du altid har landekode med, så lav en select for at dele op i de enkelte formater. Og bladr rundt på nogle sites for hvert land for at aflure deres tlf-layout.
Jeg har lige flikket noget kode sammen som måske kan hjælpe dig på vej. Det er en første version, som helt sikkert kan gøres mere effektiv, men det kan da give dig en idé til hvordan det kan gøres:
function findFormat(telefonnr) dim landekode landekode = left(telefonnr, 4) select case landekode case "0045" findFormat = "+## ## ## ## ##" case "0044" findFormat = "+## (###) ## ## ##" case "0081" findFormat = "+## (###) ### ####" case else ' returner som standard et format der bare returnerer ' telefonnr som en lang kæde af cifre uden mellemrum ' f.eks. 0041123456789 findFormat = Replace(Space(len(Replace(telefonnr, " ", ""))), " ", "#") end select end function
function formaterTelefonnr(tlf) ' preconditions: ' - tlf forventes at være en række af cifre uden mellemrum ' eller andre tegn ' - tlf forventes at starte med landekoden og at denne er ' præcis 4 cifre foranstillet med nuller, f.eks. 0045 ' eller 0001 ' - landekoden er altid 2 cifre (ellers skal løkkens start- ' indeks beregnes i stedet for hardcodes som her) dim format, tIdx, naesteCiffer, posFormat
format = findFormat(tlf)
' start på position 3 for at springe foranstillede nuller ' i landekoden over for tIdx = 3 to len(tlf) naesteCiffer = mid(tlf, tIdx, 1) posFormat = instr(format, "#") if posFormat > 0 then format = Replace(format, "#", naesteCiffer, 1, 1, vbTextCompare) else exit for end if next
formaterTelefonnr = format end function
Jeg har desuden lavet en lille testsuite, så du selv kan eksperimentere lidt med andre formater:
' =========================================================== ' Hjælpefunktioner til at facilitere testen ' =========================================================== function skrivBesked(txt) Response.Write txt & "<br>" end function
function skrivFejlBesked(txt) skrivBesked "<font color=red>" & txt & "</font>" end function
function tjekEns(faktisk, forventet, fejlTekst) if faktisk <> forventet then skrivFejlBesked fejlTekst & " Faktisk: <" & faktisk & ">, Forventet: <" & forventet & ">" else skrivBesked faktisk & " - OK" end if end function
' =========================================================== ' Testfunktioner der kalder funktioner under test og ' kontrollerer om resultatet er det forventede ' =========================================================== ' Test af formatudledning function testFindFormat(tlf, forventetOutput) dim faktiskOutput
faktiskOutput = findFormat(tlf)
tjekEns faktiskOutput, forventetOutput, "Formatet er ikke som forventet!" end function
' Test formatering af telefonnr function testTelefonnrFormatering(tlf, forventetOutput) dim faktiskOutput
faktiskOutput = formaterTelefonnr(tlf)
tjekEns faktiskOutput, forventetOutput, "Telefonnr er ikke i det forventede format!" end function
Som du kan se er dette lavet som ASP, men du kan blot udskifte Response.Write i funktionen skrivBesked, men en mere VBS-relevant måde og så burde du også være kørende med testsuiten...
Jeg har lige justeret koden til formateringen, så den kan håndtere landekoder på andet end 2 cifre:
function formaterTelefonnr(tlf) ' preconditions: ' - tlf forventes at være en række af cifre uden mellemrum ' eller andre tegn ' - tlf forventes at starte med landekoden og at denne er ' præcis 4 cifre foranstillet med nuller, f.eks. 0045 ' eller 0001 dim format, tIdx, naesteCiffer, posFormat, indledendeNul
format = findFormat(tlf)
indledendeNul = true
' start på position 3 for at springe foranstillede nuller ' i landekoden over for tIdx = 1 to len(tlf) naesteCiffer = mid(tlf, tIdx, 1) if naesteCiffer <> "0" and indledendeNul then indledendeNul = false end if
if not indledendeNul then posFormat = instr(format, "#") if posFormat > 0 then format = Replace(format, "#", naesteCiffer, 1, 1, vbTextCompare) else exit for end if end if next
'***************************************************************************************** Function SplitPhone(Number) '***************************************************************************************** Dim BackupNumber: BackupNumber = Number 'BackupNumber = "Error" 'For test only
Jeg kan godt se det smarte i din kode. Men den bliver dog nødt til at blive tilrettet lidt. F.eks. er der i Polen forskel på hvor mobil numre og fastnet numre bliver formateret. Det kan man f.eks. se på område nummeret, som kan være 1 til 4 tegn. Hvordan tjekker man så lige det?
Derudover fjerne min kode også 0'er som er sat ind, nogen gange bare som nul og andre gange som (0).
Men der er helt sikkert noget af din kode som jeg kan bruge. Jeg vil lige prøve om jeg kan forbredre min kode ud fra dit input.
Kan du give et par eksempeler på de ting du nævner (både det med polske mobil- og fastnetnumre og nuller der fjernes)? Jeg er nemlig ikke helt sikker på at jeg forstår de regler... :-)
Jeg tænker man kan lave de specielle regler for formatvalg i funktionen findFormat, således alle regler for formatvalg er pakket ind i denne funktion.
Hvis der skal laves regler for fjernelse af foranstillede nuller i en sektion af telefonnummeret, skal det, optimalt set, indarbejdes i formatet, således rutinen til tolkning af formetet kan tage sig af fjernelse af foranstillede nuller.
Men ret beset er det jo her testfunktionerne kommer til sin ret, for du angiver jo bare hvilke formater du ønsker et givet telefonnr skal komme ud i og så tilrettes koden jf. de evt. udvidede regler, mens du til stadighed sikrer dig at ALLE dine testfunktioner fortsat returnerer det ønskede resultat... :-)
Du kunne f.eks. tilføje et par kald til testFindFormat således:
Jeg kan, efter at have kigget lidt nærmere på din funktion, se der er behov for yderligere tolkning telefonnr i findFormat (det var jo også din egen point :-)). Desuden skal telefonnr normaliseres, da det åbenbart kan leveres i forskellige formater. Disse to handlinger bør nok opdeles i to funktioner, som så kaldes fra formaterTelefonnr. Altså
1. Analysér (og returnér et format) 2. Normalisér (dvs. fjern ligegyldige tegn fra telefonnr) 3. Formatér (dvs. overfør cifferstrengen til formatstrengen)
Hvis det har interesse kan jeg arbejde lidt videre med min kode, så den kommer til at leve op til de krav der er for formatering.
Function SplitPhone(Number) '***************************************************************************************** Dim BackupNumber: BackupNumber = Number 'BackupNumber = "Error" 'For test only
ElseIf Left(Number, 3) = "+44" Or Left(Number, 4) = "0044" Or Left(Number, 5) = "+(44)" Then 'UK Number Number = Replace(Number, "-", "") If Left(Number, 4) = "0044" Then Number = "+44" & Mid(Number, 5) ElseIf Left(Number, 5) = "+(44)" Then Number = "+44" & Mid(Number, 6) End If If Left(Number, 4) = "+440" Then Number = "+44(0)" & Mid(Number, 5) End If If InStr(Number, "(0)") > 0 Then '+44 (0) XXXX XXXXXX SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7, 4) & " " & Mid(Number, 11) Else '+44 XX X XXXXXXX SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 2) & " " & Mid(Number, 6, 1) & " " & Mid(Number, 7) End If
ElseIf Left(Number, 3) = "+45" Or Left(Number, 4) = "0045" Or Left(Number, 3) = "995" Or Len(Number) = 8 Or Len(Number) = 5 Then 'DK Number +45 XX XX XX XX If Left(Number, 4) = "0045" Then Number = "+45" & Mid(Number, 5, 200) End If If Len(Number) = 8 Then Number = "+45" & Number End If If Len(Number) = 5 Then Number = "+45995" & Number End If Number = StrReverse(Number) SplitPhone = StrReverse(Left(Number, 2) & " " & Mid(Number, 3, 2) & " " & Mid(Number, 5, 2) & " " & Mid(Number, 7, 2) & " " & Mid(Number, 9, 200)) ElseIf Left(Number, 3) = "+46" Or Left(Number, 4) = "0046" Then 'SE number +46 XX XXX XX XX If Left(Number, 4) = "0046" Then Number = "+46" & Mid(Number, 5) End If SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 2) & " " & Mid(Number, 6, 3) & " " & Mid(Number, 9, 2) & " " & Mid(Number, 11) ElseIf Left(Number, 3) = "+47" Or Left(Number, 4) = "0047" Then 'NO number +47 XX XX XX XX Number = StrReverse(Number) SplitPhone = StrReverse(Left(Number, 2) & " " & Mid(Number, 3, 2) & " " & Mid(Number, 5, 2) & " " & Mid(Number, 7, 2) & " " & Mid(Number, 9, 200)) ElseIf Left(Number, 3) = "+48" Or Left(Number, 4) = "0048" Then 'PL number If Left(Number, 4) = "0048" Then Number = "+48" & Mid(Number, 5) End If Select Case Mid(Number, 4, 2) Case "67", "51", "53", "60", "66", "69", "72", "78", "79", "88" 'Mobile number +48 XXX XXX XXX SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7, 3) & " " & Mid(Number, 10) Case Else 'Stationary number +48 XX XXX XX XX SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 2) & " " & Mid(Number, 6, 3) & " " & Mid(Number, 9, 2) & " " & Mid(Number, 11) End Select ElseIf Left(Number, 3) = "+49" Then 'DE Number Number = Replace(Number, "(0)", "") Number = Replace(Number, "/", "") If Len(Number) = 13 Then '+49 xxx xxx xx xx SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7, 3) & " " & Mid(Number, 10, 2) & " " & Mid(Number, 12, 250) ElseIf Len(Number) = 12 Then '+49 xxx xx xx xx SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7, 2) & " " & Mid(Number, 9, 2) & " " & Mid(Number, 11, 250) ElseIf Len(Number) = 14 Then '+49 xxx xxxxx xxx SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7, 5) & " " & Mid(Number, 12, 250) Else SplitPhone = BackupNumber End If Else 'Cant find number Language, returns the number again SplitPhone = BackupNumber End If
End Function
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.