Avatar billede bigilo Nybegynder
29. marts 2011 - 10:36 Der 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.

På forhånd tak
Avatar billede claes57 Ekspert
29. marts 2011 - 11:36 #1
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.
Avatar billede softspot Forsker
29. marts 2011 - 13:13 #2
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

' ===========================================================
' Testscenarier med forskellige input og forventede ouput
' ===========================================================
testFindFormat "004512345678", "+## ## ## ## ##"
testFindFormat "00811234567890", "+## (###) ### ####"
testFindFormat "0044123456789", "+## (###) ## ## ##"

testTelefonnrFormatering "004512345678", "+45 12 34 56 78"
testTelefonnrFormatering "00811234567890", "+81 (123) 456 7890"
testTelefonnrFormatering "0044123456789", "+44 (123) 45 67 89"

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...
Avatar billede softspot Forsker
29. marts 2011 - 13:35 #3
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

  formaterTelefonnr = format
end function
Avatar billede bigilo Nybegynder
30. marts 2011 - 09:56 #4
Her er der kode som jeg selv er kommet frem til.

'*****************************************************************************************
Function SplitPhone(Number)
'*****************************************************************************************
    Dim BackupNumber: BackupNumber = Number
    'BackupNumber = "Error" 'For test only
   
    Number = Replace(Number, " ", "")
    If Left(Number, 3) = "+31" Then
        'NL Number
        Number = Replace(Number, "(0)", "")
        Select Case Mid(Number, 4, 4)
            Case "6760" '+31 XXXX XXXXXX
                SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 4) & " " & Mid(Number, 8)
            Case Else
                Select Case Mid(Number, 4, 3)
                    Case "111", "113", "114", "115", "117", "118", "161", "162", "164", "165", "166", "167", "168", "172", "174", "180", "181", "182", "183", "184", "186", "187", "222", "223", "224", "226", "227", "228", "229", "251", "252", "255", "294", "297", "299", "313", "314", "315", "316", "317", "318", "320", "321", "341", "342", "343", "344", "345", "346", "347", "348", "411", "412", "413", "416", "418", "475", "478", "481", "485", "486", "487", "488", "492", "493", "495", "497", "499", "511", "512", "513", "514", "515", "516", "517", "518", "519", "521", "522", "523", "524", "525", "527", "528", "529", "541", "543", "544", "545", "546", "547", "548", "561", "562", "566", "570", "571", "572", "573", "575", "577", "578", "591", "592", "593", "594", "595", "596", "597", "598", "599", "800", "900", "906", "909"
                        '+31 XXX XXXXXXX
                        SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7)
                    Case Else
                        Select Case Mid(Number, 4, 2)
                            Case "10", "13", "15", "20", "23", "24", "26", "30", "33", "35", "36", "38", "40", "43", "45", "46", "50", "53", "55", "58", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "66", "84", "85", "87", "88"
                                '+31 XX XXXXXXXX
                                SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 2) & " " & Mid(Number, 6)
                            Case Else
                                Select Case Mid(Number, 4, 1)
                                    Case 6
                                        '+31 X XXXXXXXXX
                                        SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 1) & " " & Mid(Number, 5)
                                    Case Else
                                        SplitPhone = BackupNumber
                                End Select
                        End Select
                End Select
        End Select

    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
Avatar billede softspot Forsker
30. marts 2011 - 10:07 #5
Det ser kompliceret ud. Har du prøvet min version? Eller er der noget du ikke forstår ved den metode jeg illustrerer?
Avatar billede bigilo Nybegynder
30. marts 2011 - 13:54 #6
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.
Avatar billede softspot Forsker
30. marts 2011 - 14:10 #7
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.
Avatar billede softspot Forsker
30. marts 2011 - 15:03 #8
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:

testFindFormat "+44(0)1234567890", "+## (#) #### ######"
testFindFormat "+4401234567890", "+## (#) #### ######"
testFindFormat "004401234567890", "+## (#) #### ######"
testFindFormat "+441234567890", "+## ## # #######"
testFindFormat "00441234567890", "+## ## # #######"

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.
Avatar billede bigilo Nybegynder
27. juli 2011 - 09:24 #9
Her er måden jeg selv har løst problemet:

Function SplitPhone(Number)
'*****************************************************************************************
    Dim BackupNumber: BackupNumber = Number
    'BackupNumber = "Error" 'For test only
   
    Number = Replace(Number, " ", "")
    If Left(Number, 3) = "+31" Then
        'NL Number
        Number = Replace(Number, "(0)", "")
        Select Case Mid(Number, 4, 4)
            Case "6760" '+31 XXXX XXXXXX
                SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 4) & " " & Mid(Number, 8)
            Case Else
                Select Case Mid(Number, 4, 3)
                    Case "111", "113", "114", "115", "117", "118", "161", "162", "164", "165", "166", "167", "168", "172", "174", "180", "181", "182", "183", "184", "186", "187", "222", "223", "224", "226", "227", "228", "229", "251", "252", "255", "294", "297", "299", "313", "314", "315", "316", "317", "318", "320", "321", "341", "342", "343", "344", "345", "346", "347", "348", "411", "412", "413", "416", "418", "475", "478", "481", "485", "486", "487", "488", "492", "493", "495", "497", "499", "511", "512", "513", "514", "515", "516", "517", "518", "519", "521", "522", "523", "524", "525", "527", "528", "529", "541", "543", "544", "545", "546", "547", "548", "561", "562", "566", "570", "571", "572", "573", "575", "577", "578", "591", "592", "593", "594", "595", "596", "597", "598", "599", "800", "900", "906", "909"
                        '+31 XXX XXXXXXX
                        SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 3) & " " & Mid(Number, 7)
                    Case Else
                        Select Case Mid(Number, 4, 2)
                            Case "10", "13", "15", "20", "23", "24", "26", "30", "33", "35", "36", "38", "40", "43", "45", "46", "50", "53", "55", "58", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "66", "84", "85", "87", "88"
                                '+31 XX XXXXXXXX
                                SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 2) & " " & Mid(Number, 6)
                            Case Else
                                Select Case Mid(Number, 4, 1)
                                    Case 6
                                        '+31 X XXXXXXXXX
                                        SplitPhone = Left(Number, 3) & " " & Mid(Number, 4, 1) & " " & Mid(Number, 5)
                                    Case Else
                                        SplitPhone = BackupNumber
                                End Select
                        End Select
                End Select
        End Select

    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
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester