私はいくつかありますアドレス.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をここにダンプしました。