2009-03-16 7 views
2

私が書いているアプリは、ユーティリティサービスのアドレスを扱っています。今、私は、ユーザがアドレスの部分を分けて、データベースに追加する前に適切なフィールドに置くことを十分に知っています。これは、並べ替えの目的のためにこのようにしなければなりません。なぜなら、アルファベットの並べ替えは、アドレスにプリディレクションがあるときは必ずしも正しいとは限らないからです。サービスアドレスの部分を類別するための正規表現ですか?

  • ストリート番号= 123
  • 前方向= N
  • ストリート名:ユーザがサービスアドレス123 N MAIN STに入れたい場合たとえば、今、彼らは、としてそれを入力します。 =メイン
  • ストリートタイプ=セント

私は、Split関数を使用して、各部品を反復することによって、その部分にこのアドレスを分離することを試みました。私がこれまでに持っていたことは以下の通りです:

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
私は、このメソッドが厄介で、遅く、うんざりしたアドレスが与えられたときに完全に間違っていることを発見しました。私がここでやろうとしていることが正規表現に適しているのではないかと思います。確かに私は前に何でも正規表現を使用したことはありませんし、その点では初心者です。

ご協力いただきありがとうございます。 :)

編集 - 私はパーサーだけでなく、正規表現を必要とするようになります。誰もが良いアドレスパーサーライブラリを知っていますか?私たち自身を書いているのは今のところカードに入っておらず、それが来たらバックバーナーに送られます。

+0

プレディクタは常に1文字ですか? –

+0

@Stuart B - いいえ、時には人々が "123 South Main St"のように入力します –

+0

@Heather - これは間違いなくこの難しい問題をさらに毛深くします!あなたは間違いなく、受け入れ可能な先行予約の定義リストを持っていなければなりません。 –

答えて

1

私は反対(簡単に)テストへのアドレスのセットを持っていないが、ここで、少なくともしようとするものです。それはあまりにも寛容すぎるかもしれないし、他のものにはあまりにも制限的かもしれませんが、あなたはそれを微調整できなければなりません。あなたは間違いなく予選のリストを微調整する必要がありますが、に明示的に指定する必要があります。また、大文字と小文字を区別しないようにregexオプションを設定してください。

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

NoahDが提案したように、可能であればこれをアドレスパーサに委譲するほうがよいでしょう。おそらく、.NETのために何かを見つけるためにいくつかの掘り下げをしなければならないでしょうが、何も見つけられない場合は、正規表現を使用します。

編集:do'h、\ sは、ない/ sの

編集:よりセマンティックグループ化regexで変更しました。グループの値には、次のようにアクセスできます。

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

うーん...私は思います正規表現が何をしたのか、私は以前は分かりませんでした。あなたが言ったように、アドレスパーサーはおそらく私が必要としているものです。この式を.NETのRegexオブジェクトにプラグインすると、入力を検証するのに非常にうまくいったので、そのアカウントで+1します。ご協力ありがとうございました。 :) –

+0

実際には、正規表現を使用して文字列の一部を抽出することができます。私はこのようなことを不愉快に書いているので、どのグループを引っ張るべきかを知ることは難しいかもしれません。ちょうど "C#正規表現のグループ"または何かのためのGoogleの検索を行う。 –

+0

アドレスパーサについては、geocoder.usには1つあると思います。あなたがそれを支払わなければならないのかどうかわかりません。 –

0

あなたが例えばGeo::StreetAddress::US

使ってPerlでこれを行うことができます:

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

+0

これはVB.NETにはあまりにも悪いですが、これはほとんど正確に私が探しているものです。 .NETのパーサライブラリがあるかどうか知りませんか? –

+0

実際、これはもっと良いスレッドかもしれません: http://stackoverflow.com/questions/16413/parse-usable-street-address-city-state-zip-from-a-string – NoahD

関連する問題