거리 번호에서 거리 이름을 분리/추출하는 최고의 도구

거리 번호에서 거리 이름을 분리/추출하는 최고의 도구

나는 몇 가지를 가지고 있습니다주소.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를 세 번째 인수 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를 여기에 덤프했습니다.

관련 정보