4

私がこの文字列を持っているとしましょう:

<div>john doe is nice guy btw 8240 E. Marblehead Way 92808  is also</div>

またはこの文字列:

<div>sky being blue? in the world is true? 024 Brea Mall  Brea, California 92821 jackfroast nipping on the firehead</div>

これらの文字列の1つからアドレスを抽出するにはどうすればよいですか?これには、ある種の正規表現が含まれますよね?

JavaScriptまたはPHPを使用して解決策をオンラインで探してみましたが、役に立ちませんでした。そして、ここにあるStack Overflowに関する他の投稿(私が知る限り)は、jQueryおよび/またはJavascriptおよび/またはPHPを使用するソリューションを提供していません。(最も近いのは、文字列から使用可能な番地、市区町村、都道府県、郵便番号を解析することです。これには、文字列から郵便番号を抽出するためのコードがスレッドに含まれていません。

誰かが私を正しい方向に向けることができますか?jQuery、JavaScript、またはPHPでこれを実現するにはどうすればよいですか?

4

6 に答える 6

23

あなたのものに似ている12の異なるストリングでこれを試してみました、そしてそれはうまくいきました:

function str_to_address($context) { 

    $context_parts = array_reverse(explode(" ", $context)); 
    $zipKey = ""; 
    foreach($context_parts as $key=>$str) { 
        if(strlen($str)===5 && is_numeric($str)) { 
            $zipKey = $key;
            break; 
        }
    }

    $context_parts_cleaned = array_slice($context_parts, $zipKey); 
    $context_parts_normalized = array_reverse($context_parts_cleaned); 
    $houseNumberKey = ""; 
    foreach($context_parts_normalized as $key=>$str) { 
        if(strlen($str)>1 && strlen($str)<6 && is_numeric($str)) { 
            $houseNumberKey = $key;
            break; 
        }
    }

    $address_parts = array_slice($context_parts_normalized, $houseNumberKey);
    $string = implode(' ', $address_parts);
    return $string;
}

これは、家番号が2桁以上、6桁以下であることを前提としています。これは、郵便番号が「拡張」形式(12345-6789など)ではないことも前提としています。ただし、これはその形式に合わせて簡単に変更できます(ここでは、のような正規表現が適切なオプションです(\d{5}-\d{4})

しかし、ユーザーが入力したデータを解析するために正規表現を使用する...検証がなかったため、ユーザーが何を入力するのかわからないため、ここではお勧めできません。

コンテキストから配列を作成し、zipを取得することから始めて、コードとロジックをウォークスルーします。

// split the context (for example, a sentence) into an array, 
// so we can loop through it. 
// we reverse the array, as we're going to grab the zip first. 
// why? we KNOW the zip is 5 characters long*.
$context_parts = array_reverse(explode(" ", $context));  

// we're going to store the array index of the zip code for later use 
$zipKey = ""; 

// foreach iterates over an object given the params, 
// in this case it's like doing... 
// for each value of $context_parts ($str), and each index ($key)
foreach($context_parts as $key=>$str) { 

    // if $str is 5 chars long, and numeric... 
    // an incredibly lazy check for a zip code...
    if(strlen($str)===5 && is_numeric($str)) {  
        $zipKey = $key;

        // we have what we want, so we can leave the loop with break
        break; 
    }
}

家番号を取得するためのより良いオブジェクトがあるように、いくつかの整理を行います

// remove junk from $context_array, since we don't 
// need stuff after the zip
$context_parts_cleaned = array_slice($context_parts, $zipKey); 

// since the house number comes first, let's go back to the start
$context_parts_normalized = array_reverse($context_parts_cleaned);

次に、郵便番号を使用したのと同じ基本ロジックを使用して、家番号を取得しましょう。

$houseNumberKey = ""; 
foreach($context_parts_normalized as $key=>$str) { 
    if(strlen($str)>1 && strlen($str)<6 && is_numeric($str)) { 
        $houseNumberKey = $key;
        break; 
    }
}

// we probably have the parts we for the address.
// let's do some more cleaning 
$address_parts = array_slice($context_parts_normalized, $houseNumberKey);

// and build the string again, from the address
$string = implode(' ', $address_parts);

// and return the string
return $string;
于 2013-01-02T00:16:40.920 に答える
2

正規表現は、パターンに対してテストするために使用されます。あなたはあなたが探しているパターンを知る必要があります。あなたが提供した2つの例から、数字を探し、次に5桁の数字で終わるテキストを探します。

すべてのアドレスはこの形式である必要があります。文字列からアドレスを魔法のように抽出することはできません。

于 2012-12-30T00:15:15.797 に答える
2

すべてのアドレスの開始と終了が数字である場合、この正規表現を使用して必要なデータを抽出できます。

/[0-9].+[0-9]/gi

Javascriptの例:

"<div>john doe is nice guy btw 8240 E. Marblehead Way 92808  is also</div>".match(/[0-9].+[0-9]/gi) // ["8240 E. Marblehead Way 92808"]
"<div>sky being blue? in the world is true? 024 Brea Mall  Brea, California 92821 jackfroast nipping on the firehead</div>".match(/[0-9].+[0-9]/gi) // ["024 Brea Mall  Brea, California 92821"]

電話番号を含む新しい例では、次のことができます。

/[0-9].*[0-9]/gi

Javascriptの例:

"john doe 7143138656 is 8240 e marblehead way 92808".match(/[0-9].*[0-9]/gi) // ["7143138656 is 8240 e marblehead way 92808"]

ただし、これは、行ごとに一致情報がある場合にのみ役立ちます。強力なアドレスマッチャーが本当に必要な場合は、先に進んで強力な分析を作成する必要があります。

テキストでターゲットキーワードの検索を開始し、次にパラグラフをフィルタリングして、探している情報を取り除くことができます。

簡単な質問ではありませんが、実行できます。一部の一致には複数の正規表現を使用できますが、アドレスにパターンがない場合、正規表現は役に立たないため、アプローチを変更する必要があります。

于 2012-12-30T13:34:44.327 に答える
1

便宜上、正規表現を使用してすべてを解析しようとするのはよくある「間違い」です。ただし、正規表現がすべての答えになるわけではありません。この場合、テキストの規則的なパターンを探しているようには見えませんが、誰かがあなたと話しているかのように書く「自然な」表現です。これらの自然な表現は、必ずしも一貫したパターンに従うとは限りません。最初にappt番号を入力してから建物番号を入力する人もいれば、都市を省略して郵便番号にスキップする人もいれば、都市、州、国を入力してからzipを入力する人もいます。誰かが住所で作り上げる可能性のあるすべての正規表現パターンを列挙することは不可能です。

自然言語アドレスの場合、正規表現アドレスの検出を忘れて、ステートフル解析アルゴリズムに移行します。

  1. まず、テキストを左から右に(少なくとも英語で)一度に1語ずつ読みます。各単語で、「この単語は住所の始まりである可能性がありますか?」という1つの論理テストを実行します。これは、建物番号またはappt / unit / box番号のいずれかの番号だと思います(つまり、「Box XXX」、「PO BOX XXX」、「PO XXX」、「Unit XXX」、「#XXX」、またはそれ以下の番号)長さが6桁を超える)。これが事実であるかどうかはわかりませんが、電話の最小長である長さ7桁の北米の建物を見たことがありません。ですから、電話番号と建物番号をかなり簡単に分類できるのではないかと思います。この「アドレスの開始」テストは、正規表現の一致のセットである可能性がありますが、アドレス全体と一致しているわけではありません。アドレスを開始する単語やフレーズをテストするだけです。たぶんそうなると言ってもいいでしょう正規表現のマッチングなしでよりシンプルに

  2. アドレスの開始を検出したら、「アドレス解析状態オブジェクト」を作成します(継続的な解析としてアドレスを保持し、これまでの内容と次に期待する内容を追跡するために使用するクラス)。これで、文をステップ実行し続け、パーサー状態オブジェクトに追加し続けることができます。建物番号に続いて、おそらく通りの名前または方向指示器(NEWS NE。NW。SE。SW。)を期待します。次にどちらも来ない場合は、アドレスの解析を停止し、無効または不完全なアドレスを想定し、アドレスの新しい開始ワードを探し続けます。それ以外の場合は、通りの名前や方向インジケーターを解析ツリーに追加して続行します。

  3. 通りの名前に続くものはすべて無限に変化する可能性があります。一部のユーザーは、建物番号と通りの名前にとどまる場合があります(地元の都市/地域/国を想定)。それ以外の場合は、おそらく都市名または郵便番号/郵便番号のいずれかを探しています。見つかった場合は、住所解析状態オブジェクトに追加します。そうでない場合は、不完全な住所(ユーザーのデフォルトの場所情報を入力しますか?)または無効な住所(無視して、別の住所の開始点を探し続けますか?)を想定します。

最終的に、このアプローチは、おそらく数百行のコードを含むかなり単純なJavaScriptメソッドである可能性があります(私はPHPの人ではありませんが、似ていると思います)。考えられるすべての正規表現パターンを列挙しようとすると、誰かがアドレスを作成する可能性があります。数百もの正規表現があり、それでも信頼性は低くなります。(何百もの正規表現パターンを一致させようとしている場合は、おそらく速度も遅くなります)。

于 2013-01-01T20:16:44.087 に答える
0

GoogleGeocodeAPIを使用して幸運を祈りました。アドレス文字列を入力する可能性のあるすべての方法を考えるのは困難です。

最近、不動産Webサイトの単一の文字列から住所の一部を抽出する必要がありましたが、最良のオプションはgooglegeocodeAPIを使用することであることがわかりました。入力したすべての住所について、Street、City、State、Zip、Latitude、Longitudeなどを取得できました。

ここで、google geocode API(PHP)をセットアップするための優れたガイドを見つけました:http ://www.andrew-kirkpatrick.com/2011/10/google-geocoding-api-with-php/

最良の部分は、場所の名前でも機能します。したがって、「UCLA」または「Apple Headquarters」を検索すると、必要になる可能性のあるアドレスのすべての部分が表示されます。

于 2013-07-17T04:48:02.887 に答える
-1

私の考えでは、「ここからここまでのフォームはアドレスであり、残りは単純なテキストである」というコードを伝えるための何かが必要だと思います。そのためには、アドレスの配列を作成するか、挿入された値と比較できるデータベースにアドレスを保持します。

于 2013-01-01T10:41:00.157 に答える