ストリート番号からストリート名を分離/抽出するための最高のツール

ストリート番号からストリート名を分離/抽出するための最高のツール

私はいくつかありますアドレス.csv様々な国際形式

Example Street 1
Teststraße 2
Teststr. 1-5
Baker Street 221b
221B Baker Street
19th Ave 3B
3B 2nd Ave
1-3 2nd Mount x Ave
105 Lock St # 219
Test Street, 1
BookAve, 54, Extra Text 123#

例えば、私たちはドイツで書いて、Teststraße 2アメリカで書いています。2 Test Street

道路名と道路番号の両方を分離/抽出する方法はありますか? 出力名.csv

Example Street
Teststraße
Teststr.
Baker Street
Baker Street
19th Ave
2nd Ave
2nd Mount Good Ave
Lock St # 219
Test Street
BookAve

出力番号.csv

1
2
1-5
221b
221B
3B
3B
1-3
105
1
54

出力-extra_text.csv











Extra Text 123#

私はmacOS 13を使用しています。シェルは zsh 5.8.1 または bash-3.2 です。


私の考えは、次のようにアドレスを最初に並べ替えることです。

x=The-adress-line;
if [ x = "begins with a letter"];
    then 
    if [ x = "begins with a letter + number + SPACE"];
        then
        echo 'something like "1A Street"';
        # NUMBER = '1A' / NAME = 'Street'
    else
        echo 'It begins with the STREET-NAME';
    fi;
elif [ x = "begins with a number"];
    then
    echo 'maybe STREET-NAME like "19th Ave 19B" or STREET-NUMBER like "19B Street"';
    # NUMBER = '19B' / NAME = '19th Ave' or 'Street'
    if [ x = "begins with a number + SPACE"];
        then
        echo 'It begins with the STREET-NUMBER like "1 Street"';
        # NUMBER = '1' / NAME = 'Street'
    elif [ x = "is (number)(text)(space)(text)(number(maybe-text))"];
        then
            echo 'For example 19th Street 19B -> The last number+text is the number (19B)'
            # NUMBER = '19B' / NAME = '19th Street'
    elif [ x = "is (number(maybe-text))(space)(number)(text)(space)(text)"];
        then
        echo 'For example 19B 19th Street -> The first number+text is the number (19B)'
            # NUMBER = '19B' / NAME = '19th Street'
    else
        echo 'INVALID';
else
    echo 'INVALID';
fi;

答え1

IMHO、あなたができることは、あなたが知っているアドレスと一致するように一連の正規表現を使用することです。たとえば、GNU awkを3番目の引数match()\s略語として使用し、[[:space:]]3つの可能な定義済み正規表現を使用します。

$ cat tst.awk
BEGIN { OFS="\",\"" }
{
    name = number = type = ""
    gsub(/"/,"\"\"")
}
match($0,/^([^0-9]+)([0-9]+(-[0-9]+)?[[:alpha:]]?)$/,a) {
    # Example Street 1
    # Teststraße 2
    # Teststr. 1-5
    # Baker Street 221b
    # Test Street, 1
    type   = 1
    name   = a[1]
    number = a[2]
}
!type && match($0,/^([0-9]+[[:alpha:]])\s+([^0-9]+)$/,a) {
    # 221B Baker Street
    type   = 2
    name   = a[2]
    number = a[1]
}
!type && match($0,/^([0-9]+[[:alpha:]]{2}.*)\s+([0-9]+[[:alpha:]]?)$/,a) {
    # 19th Ave 3B
    type   = 3
    name   = a[1]
    number = a[2]
}
{
    gsub(/^\s+|\s+$/,"",name)
    gsub(/^\s+|\s+$/,"",number)
    if ( !doneHdr++ ) {
        print "\"" "type", "name", "number", "$0" "\""
    }
    print "\"" type, name, number, $0 "\""
}

$ awk -f tst.awk file
"type","name","number","$0"
"1","Example Street","1","Example Street 1"
"1","Teststraße","2","Teststraße 2"
"1","Teststr.","1-5","Teststr. 1-5"
"1","Baker Street","221b","Baker Street 221b"
"2","Baker Street","221B","221B Baker Street"
"3","19th Ave","3B","19th Ave 3B"
"","","","3B 2nd Ave"
"","","","1-3 2nd Mount x Ave"
"","","","105 Lock St # 219"
"1","Test Street,","1","Test Street, 1"
"","","","BookAve, 54, Extra Text 123#"

適切な順序で知っているアドレスパターンと一致するように、追加の正規表現を追加できます。これにより、アドレスが2つ以上の正規表現と一致できる場合は、より制限的な正規表現を最初に取得できます。アドレスが2つ以上の正規表現と一致する場合に警告を印刷するように上記の内容を実際に変更し、それを調整、並べ替え、またはマージできます。

printそれでも空の行に達すると、typeこれは「間違った」ケースであるため、その行に一致する新しい正規表現を作成/追加できます(該当する場合)。

あるアドレス形式を他のアドレス形式と区別するコードを書くことができない状況に直面することが予想されますが、この最善のアプローチはあなたの要件に十分であることを願っています。都市/州/郡がある場合は、識別できない住所への最後の努力で、いつでもGoogleマップを使用して住所をカールして、住所が本物であることを確認できます(ただし、それがすべてであれば時間がかかります)。すべての住所について)。

アドレス認識アルゴリズムが機能すると、必要に応じて出力を生成できます。開発/テストの容易さのためにCSVをここにダンプしました。

関連情報