Parser ulic (Ulica, dom, lokal)

0

Witam.

Potrzebuję rozdzielić adres na trzy części. Ulica, dom i lokal. Obecnie dana ta jest w jednym ciągu znaków.

Pytanie brzmi: Czy ktoś już borykał się z tym problemem i może podzielić się doświadczeniami? Być może istnieje sprawdzona metoda na rozczłonowanie tego typu?

Problem polega na tym, iż ludzie piszą różnie: "ul. Jana Pawła 2 223 m. 2", "ul. Jana Pawła II 223/2", "ul. Jana Pawła II 223 / 2", "ul. Jana Pawła II 223/m2"... sposobów jest bardzo dużo...

0

koniec końców i tak musisz organoleptycznie to potem sprawdzić

1

Jeżeli masz możliwość uniknięcia tego koszmaru, zrób to. Zamiast podawać jedno pole tekstowe "adres" rozbij je na kilka pól tekstowych: "nazwa ulicy" "nr domu/mieszkania" "miejscowosc" "kod pocztowy"... ;)
edit:
Jeśli brać pod uwagę tylko te propozycje, to możesz wyciągać od prawej liczbę (nr mieszkania), kolejną liczbę (nr domu) - a resztę potraktować jako nazwę ulicy (wycinając ew. "ul." na początku(albo lepiej nie ;) )).

0

Nie można też zapomnieć, że w nr domu jak i lokalu mogą pojawić się litery np. ul. XXX 23a m. 56b

1

Imo, wycinanie "ul." jest niedopuszczalne. Są adresy "ul.Krótka 1234 m5" i adresy "os.Bałuty 4/6". W moim mieście jest "ul.Kopernika" i "Os.Kopernika".

0

Samotna (nieotoczona innymi literami) litera m bądź m. bądź slash czy tam backslash oddzielają numerr budynku od numeru lokalu. Zatem to co na prawo, to lokal.
To co na lewo, to numer budynku, który kończy się (bo analizujemy od tyłu, z punktu widzenia człowieka jest to początek) na pierwszym znaku, który nie jest cyfą.
Reszta to nazwa ulicy, osiedla, alei, placu, itd.

Zgadłem?

1

nie zapomnij o wsiach: jeśli nie jest to wieś-siedziba gminy, to nie ma ulic, tylko zamiast ulicy, podaje się właśnie nazwę wsi, a zamiast miasta nazwę gminy ;)

najleopiej zrobić tak jak napisał azrael - rozbić na kilka pól i się nie bawić

2

I tak znajdzie się ktoś mieszkający na tyle nietypowo, że twój parser rozwali mu adres. Jedyną rzecz, którą sensownie można parsować to kod pocztowy.
IMHO jedyne szczęśliwe rozwiązanie jest w formularzach bankowych, np. w Inteligo: masz 4 linijki na wpisanie adresu bez żadnego dzielenia na pola typu „ulica”, „numer domu”, i bez żadnej walidacji. Nie każdy ma nazwę ulicy, nie zawsze jest to „ulica”, czasem ktoś mieszka na takim zadupiu że ma własną nazwę miejscowości, na wsiach często poczta jest w innej miejscowości, a w miastach często numery mają literki. Nie da się tak napisać parsera czy regexpa żeby objąć wszystko, bo nie wszystko da się przewidzieć.

2

Zakładając, że mamy tylko jedną linijkę w której jest miejscowość/ulica, nr domu i opcjonalnie numer mieszkania (w tej kolejności) to jeszcze cos możemy ugrać, ale i tak będą przypadki dwuznaczne. Ktoś pewnie napisze lepszy przykład, no ale nie myli się tylko ten, kto nic nie robi. ;)

Mały test:

#!perl
use 5.010;
use strict;

while(<>) {
    chomp;
    say;
    if (/.+(\s\d+\w{0,3})[^\d]+(\d+\w{0,3})/) {
        s/(.+)(\s\d+\w{0,3})([^\d]+(\d+\w{0,3}))/ulica: '$1'\nnr domu: $2\nnr mieszkania: $4\n/;
    } else {
        s/(.+)(\s\d+\w{0,3})/miejscowosc: '$1'\nnr domu: $2\n/;
    }
    say;
}
$ ./adres.pl adresy
ul. Jana Pawła II 223/m2
ulica: 'ul. Jana Pawła II'
nr domu:  223
nr mieszkania: 2

ul. Jana Pawła 2 223 m. 2
ulica: 'ul. Jana Pawła 2'
nr domu:  223
nr mieszkania: 2

ul. Jana Pawła II 223/2
ulica: 'ul. Jana Pawła II'
nr domu:  223
nr mieszkania: 2

ul. Jana Pawła II 223 / 2
ulica: 'ul. Jana Pawła II'
nr domu:  223
nr mieszkania: 2

al. Alfreda Hiczkoka-Czwartego, 154a/23c
ulica: 'al. Alfreda Hiczkoka-Czwartego,'
nr domu:  154a
nr mieszkania: 23c

os. Agnieszki Osieckiej 22,2
ulica: 'os. Agnieszki Osieckiej'
nr domu:  22
nr mieszkania: 2

ul. Pasiasta 32a mieszkania 5
ulica: 'ul. Pasiasta'
nr domu:  32a
nr mieszkania: 5

Marszałkowo 512
miejscowosc: 'Marszałkowo'
nr domu:  512

Mysia Wólka 15
miejscowosc: 'Mysia Wólka'
nr domu:  15

os. Diabełka 666m.3
ulica: 'os. Diabełka'
nr domu:  666m <<<<< Czy m jest częścią numeru czy już oznacza mieszkanie? (zignorujmy kropkę)
nr mieszkania: 3

os. Diabełka 666aa m. 33aa
ulica: 'os. Diabełka'
nr domu:  666aa
nr mieszkania: 33aa

os. Diabełka 666aa m32ac
ulica: 'os. Diabełka'
nr domu:  666aa
nr mieszkania: 32ac

Jeżeli w jednym stringu mamy cały adres, to nam się troszkę sprawa komplikuje (ale jeżeli znakami nowej linii oddzielone są jego części, to troszke mniej) - tak czy inaczej, jeżeli adres jest potrzebny, a nie od picu, to tak czy siak trzeba go będzie zweryfikować... I zweryfikowany pewnie wklepać ręcznie.
I nowe miejsce pracy gotowe. ;)

edit:
No i już przy "ul. Jana Pawła 2 223" się posypie: "ulica: ul. Jana Pawła, nr domu 2, mieszkania 223. ;)

0

A tak w ogóle, to jaki cel ma zostać osiągnięty?

0
somekind napisał(a)

A tak w ogóle, to jaki cel ma zostać osiągnięty?

Jest sobie baza danych, na którą nie mam wpływu (struktura). W niej adres jest w jednym ciągu "Jana Pawła II 123a/32". Ja potrzebuję adresy te zaciągnąć do drugiej bazy, na którą również nie mam wpływu, a w której konieczne jest rozdzielenie ulicy domu i lokalu.

somekind napisał(a)

Samotna (nieotoczona innymi literami) litera m bądź m. bądź slash czy tam backslash oddzielają numerr budynku od numeru lokalu. Zatem to co na prawo, to lokal.
To co na lewo, to numer budynku, który kończy się (bo analizujemy od tyłu, z punktu widzenia człowieka jest to początek) na pierwszym znaku, który nie jest cyfą.
Reszta to nazwa ulicy, osiedla, alei, placu, itd.

Tak zgadłeś, ale istota samego problemu jest dużo bardziej problematyczna. Przejżyj przykłady ulic podane przez Azrael_Valedhel dwa posty wyżej.

0

odświeżam temat bo mam rozwiązanie może komuś się jeszcze przyda

kod w c#

var x = textBox1.Text.Split(' ');
            string ulica ="";
            string nr ="";
            string lok="";
            int _l;
            for (int i = 0; i < x.Length; i++)
            {
                if(x[i].Any(z=>int.TryParse(z.ToString(),out _l)))
                {
                    if (string.IsNullOrEmpty(nr))
                    {
                        if (i == x.Length - 1)
                        {
                            var _pom = x[i].Split('/');
                            nr = _pom[0];
                            if (_pom.Length > 1) lok = _pom[1];
                        }
                        else nr = x[i];
                    }
                    else lok = x[i];
                }
                else
                {
                    if (string.IsNullOrEmpty(nr) && string.IsNullOrEmpty(lok)) ulica += " "+x[i];
                }
            }
0

Przy 'ul. 1 Maja 23' jest tylko "ul." zamiast "ul. 1 Maja"

1 użytkowników online, w tym zalogowanych: 0, gości: 1