2009-03-16 10 views
2

L'application que je suis en train d'écrire traite des adresses de services publics, et en ce moment je force l'utilisateur de connaître assez pour séparer les parties de l'adresse et de les mettre dans les champs appropriés avant d'ajouter à la base de données. Cela doit être fait de cette manière à des fins de tri parce qu'un tri alphabétique direct n'est pas toujours correct lorsqu'il y a une pré-direction dans l'adresse. Par exemple, en ce moment, si l'utilisateur a voulu mettre l'adresse de service 123 N Main St, ils entreraient comme:Expression régulière pour catégoriser les parties d'une adresse de service?

  • rue Number = 123
  • Pré direction = N
  • Nom Rue = principal
  • rue type = St

J'ai essayé de séparer cette adresse dans ses parties en utilisant la fonction Split et itérer chaque partie. Ce que j'ai jusqu'ici est ci-dessous:

Public Shared Function ParseServiceAddress(ByVal Address As String) As String() 
     'this assumes a valid address - 101 N Main St South 
     Dim strResult(5) As String '0=st_num, 1=predir, 2=st_name, 3=st_type, 4=postdir 
     Dim strParts() As String 
     Dim strSep() As Char = {Char.Parse(" ")} 
     Dim i As Integer 
     Dim j As Integer = 0 
     Address = Address.Trim() 
     strParts = Address.Split(strSep) 'split using spaces 
     For i = 0 To strParts.GetUpperBound(0) 
      If Integer.TryParse(strParts(i), j) Then 
       'this is a number, is it the house number? 
       If i = 0 Then 
        'we know this is the house number 
        strResult(0) = strParts(i) 
       Else 
        'part of the street name 
        strResult(2) = strResult(2) & " " & strParts(i) 
       End If 
      Else 
       Select Case strParts(i).ToUpper() 
        Case "TH", "ND" 
         'know this is part of the street name 
         strResult(2) = strResult(2) & strParts(i) 
        Case "NORTH", "SOUTH", "EAST", "WEST", "N", "S", "E", "W" 
         'is this a predirection? 
         If i = 1 Then 
          strResult(1) = strParts(i) 
         ElseIf i = strParts.GetUpperBound(0) Then 
          'this is the post direction 
          strResult(4) = strParts(i) 
         Else 
          'part of the name 
          strResult(2) = strResult(2) & strParts(i) 
         End If 
        Case Else 
         If i = strParts.GetUpperBound(0) Then 
          'street type 
          strResult(3) = strParts(i) 
         Else 
          'part of the street name 
          strResult(2) = strResult(2) & " " & strResult(i) 
         End If 
       End Select 
      End If 
     Next i 
     Return strResult 
    End Function
J'ai trouvé que cette méthode était lourde, lente, et même totalement erronée lorsqu'on lui donnait une adresse bancale. Je me demande si ce que j'essaie de faire ici serait une bonne application pour une expression régulière? Certes, je n'ai jamais utilisé regex dans quelque chose avant et je suis un débutant total à cet égard.

Merci d'avance pour toute aide. :)

Édition - Semble de plus en plus comme je vais avoir besoin d'un analyseur et pas seulement regex. Est-ce que quelqu'un sait de bonnes bibliothèques d'analyseurs d'adresses dans .NET? Ecrire le nôtre n'est tout simplement pas dans les cartes en ce moment, et serait envoyé à l'arrière-plan si cela arrivait à cela.

+0

La direction est-elle toujours une lettre? –

+0

@Stuart B - Non, parfois les gens les tapent comme "123 South Main St" –

+0

@Heather - cela rend définitivement ce problème difficile encore plus poilu! Vous devrez certainement avoir une liste définie de prédirections acceptables. –

Répondre

1

Je n'ai pas un ensemble d'adresses (facilement) épreuve contre, mais voici quelque chose à essayer au moins. Il peut être trop permissif dans certains endroits ou trop restrictif dans d'autres, mais vous devriez être capable de le modifier. Vous aurez certainement besoin de modifier la liste des prédirections, mais vous devrez les spécifier explicitement. Veillez également à définir vos options regex pour qu'elles ne soient pas sensibles à la casse.

^(?<StreetNumber>[0-9]+)\s*(?<Predirection>(n)|(s)|(e)|(w)|(north)|(south)|(east)|(west))?\s+(?<StreetName>[a-z0-9 -'.]+)\s+(?<StreetType>[a-z.]+)$ 

En réalité cependant, il serait sans doute préférable de confier cette tâche à un analyseur d'adresse si possible, comme celui NoahD suggéré. Vous devrez creuser pour trouver quelque chose pour .NET probablement, mais si vous ne trouvez rien, alors j'irais avec une expression régulière à coup sûr.

modifier: do'h, \ s, pas/s

modifier: modification regex pour plus regroupement sémantique. Vous pouvez accéder aux valeurs de groupe comme suit:

string address = "123 n main st"; 
Regex regex = new Regex("insert the regex above here", RegexOptions.IgnoreCase); 
MatchCollection matches = regex.Matches(address); 

foreach(Match match in matches) 
{ 
    string streetAddress = matches.Groups["StreetAddress"]; 
    string predirection = matches.Groups["Predirection"]; 
    string streetName = matches.Groups["StreetName"]; 
    string streetType = matches.Groups["StreetType"]; 
} 
+0

Hmmm ... je pense Je n'ai pas tout à fait compris ce que regex a fait auparavant. Comme vous l'avez dit, un analyseur d'adresses est probablement ce dont j'ai besoin. Brancher cette expression dans l'objet Regex de .NET a très bien fonctionné pour valider mon entrée, donc +1 sur ce compte. Merci de votre aide. :) –

+0

En fait, vous pouvez utiliser regex pour extraire des parties d'une chaîne. J'ai en quelque sorte écrit celui-ci négligemment, donc il peut être plus difficile de savoir quels groupes tirer. Il suffit de faire une recherche google pour "C# groupes Regex" ou quelque chose. –

+0

En ce qui concerne un analyseur d'adresse, je pense que geocoder.us en a un. Je ne sais pas si vous devez payer pour cela ou pas, cependant. –

0

Vous pouvez le faire en Perl utilisant Geo::StreetAddress::US

Par exemple:

 
    my $hashref = Geo::StreetAddress::US->parse_address(
       "1600 Pennsylvania Ave, Washington, DC"); 

+0

Dommage que ce soit dans VB.NET, parce que c'est presque exactement ce que je cherche. Vous ne savez pas s'il existe des bibliothèques d'analyseurs dans .NET? –

+0

En fait, cela pourrait être le meilleur fil: http://stackoverflow.com/questions/16413/parse-usable-street-address-city-state-zip-from-a-string – NoahD

Questions connexes