Results 1 to 12 of 12

Thread: Delphi 7 nummers zoeken in string

  1. #1

    Post Delphi 7 nummers zoeken in string

    Hallo allemaal,

    Zal me eerst even voorstellen, ik ben Roel en al een tijdje aan het stoeien met Delphi, wat me ook wel redelijk lukt, al zeg ik zelf :-) geen zware applicaties maar gewoon wat database-jes en zo.
    Ik heb al een aantal dagen mijn vriend google geraadpleegd, maar denk dat hij het ook niet meer weet vandaar dat ik het hier in de groep gooi.

    ik heb een string genaamd 'adres_nummer' en die is gevuld met "Concertlaan 66", ik wil die splitsen in straatnaam en nummer, dus doe ik:

    Delphi Code:
    1. iiii:= integer;
    2. ad, num, adres_nummer:= string;
    3.  
    4.   iiii:= pos(#32,adres_nummer);
    5.   ad:= Copy(adres_nummer, 1, iiii-1);
    6.   num:= copy(adres_nummer, iiii+1, length(adres_nummer));

    waarbij 'ad' gevuld wordt met de 'Concertlaan en 'num' wordt gevuld met '66'.

    joehee, dit werkt goed, maaaar als ik de volgende string wil splitsen dan gaat het totaal niet goed.

    Mijn 'adres_nummer' is nu gevuld met "Hendrik van Viandenstraat 35 1", maar als ik de bovenstaande regels toepas wordt mijn 'ad' gevuld met 'Hendrik' en mijn 'num' met 'van viandenstraat 35 1', niet goed dus.

    Ik kan het oplossen, maar dan moet ik niet met 'pos' zoeken naar #32(spatie) in mijn 'adres_nummer' maar dan zou ik in mij 'adres_nummer' moeten zoeken naar de positie van de eerste numerieke karakter in de string en daar gaan splitsen, maar daar ligt bij mij juist het probleem, hoe doe ik dat? ik heb wel voorbeelden voorbij zien komen, maar die haalt ook mijn spatie tussen 35 en 1 weg.

    Ik ben de wanhoop nabij :-(

    Groet, Roel
    Last edited by GolezTrol; 04-Sep-17 at 12:22.

  2. #2
    Welkom Roel,

    Je begint gelijk met een "zwaar" probleem. Het lijkt vrij simpel en het zoeken naar het eerste nummer is niet zo moeilijk. Maar het onderwerp van splitsen van adres naar straat en nummer is zoveel complexer als jij hier aangeeft.

    Lees het volgende onderwerp maar eens:
    http://www.nldelphi.com/showthread.p...-en-toevoeging
    De op een na laatste post heeft een functie GetFirstNumPos die jij zoekt.

    Maar daar zie je bijvoorbeeld dat je met het adres "Plein 1940 28b" al de mist in zou gaan als je naar het eerste nummer scant.

    Mijn advies in dat topic was dan om het andersom te scannen. Dus van rechts naar links. Je zoekt dan van rechts naar het eerste getal (laatste getal in de string). Alles wat erachter staat is de toevoeging. Daarna scan je door naar het eerste "niet getal" zoals een letter. Alles wat daar dan tussen staat is het nummer. Alles ervoor is de staat.

    Dit gaat dan in de meeste gevallen goed.

    Klein voorbeeldje.
    Delphi Code:
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   Adres: String = 'Plein 1940 28b';
    4.   I: Integer;
    5.   Toevoeging: String;
    6.   Nummer: String;
    7.   Straat: String;
    8. begin
    9.   I := Length(Adres);
    10.   while (I > 0) and not(CharInSet(Adres[I], ['0'..'9'])) do Dec(I);
    11.   Toevoeging := trim(Copy(Adres, I + 1, 255));
    12.   Adres := Copy(Adres, 1, I);
    13.   while (I > 0) and not(CharInSet(Adres[I], [' ', 'A'..'z'])) do Dec(I);
    14.   Nummer := trim(Copy(Adres, I + 1, 255));
    15.   Straat := trim(Copy(Adres, 1, I));
    16.   Showmessage('Straat = ' + Straat + #13 + 'Nummer = ' + Nummer + #13 + 'Toevoeging = ' + Toevoeging);
    17. end;

    Ook dit kan nog steeds mis gaan bij bijvoorbeeld adres "Plein 1940 28 - 30c"

    Zo zie je dat het een stuk moeilijker is dan dat je eerst gedacht had.

    Er zijn overigens ook tabellen die de straten bevatten in Nederland die een getal in zich hebben. Als je die tabel zou hebben dan kun je richting de 100% zekerheid van correct converteren.

    PS. Is dat adres "Hendrik van Viandenstraat 35 1" een goed adres. Waar staat die 1 voor? Mijn routine ziet dat natuurlijk als enig nummer waardoor "Hendrik van Viandenstraat 35" de complete straat is.

  3. #3
    Hoi Rik,

    Was is al bang voor dat het een zwaar probleem zou worden, want wat jij ook zegt, je hebt straatnamen met nummers erin, maar ik trek een site met adressen leeg en die adressen worden gesplitst in edit-velden weergegeven, dus ik kan corrigeren voordat ik het naar een DB schrijf, maar een adres met voorvoegsel komt vele malen vaker voor dan een straatnaam met cijfers, vandaar dat ik op zoek was naar een oplossing.

    PS. die 1 is een Bis nummer zeg maar, hier een voorbeeltje .

    maar bedank, ik ga die links van jou aandachtig bekijken en voor eventuele vragen meld ik me hier weer .

    groet, Roel

  4. #4
    Ok, die is nieuw voor mij

    Maar ik zie daar ook dat 57 1 ook vaak als 57-1 geschreven wordt. En dan kan het wel weer als nummer gedetecteerd worden.

    Je kunt dus de GetFirstNumPos() in dat topic gebruiken om het eerste nummer te zoeken of mijn hierboven genoemde code om van achteraf terug te zoeken. Kijk maar wat het handigste is.

    (in beide code-stukjes kun je in ieder geval zien hoe je van voor naar achter en van achter naar voor kunt scannen naar getallen of letters)

    Happy coding...

  5. #5
    Welkom Roel!

    Denk dat je met de Geocoding API redelijk goede resultaten kunt behalen. Je kunt dan het adres opgeven en je krijg dan een uitgesplitst resultaat terug. (JSON is niet correct door knip en plakwerk).
    Code:
    	
    results	
    0	
    address_components	
    0	
    long_name	"123"
    short_name	"123"
    types	
    0	"street_number"
    1	
    long_name	"Hoofdstraat"
    short_name	"Hoofdstraat"
    types	
    0	"route"
    2	
    long_name	"Apeldoorn"
    short_name	"Apeldoorn"
    types	
    0	"locality"
    1	"political"
    3	
    long_name	"Apeldoorn"
    short_name	"Apeldoorn"
    types	
    0	"administrative_area_level_2"
    1	"political"
    4	
    long_name	"Gelderland"
    short_name	"GE"
    types	
    0	"administrative_area_level_1"
    1	"political"
    5	
    long_name	"Nederland"
    short_name	"NL"
    types	
    0	"country"
    1	"political"
    6	
    long_name	"7311 AT"
    short_name	"7311 AT"
    types	
    0	"postal_code"
    formatted_address	"Hoofdstraat 123, 7311 AT Apeldoorn, Nederland"
    geometry	
    location	
    lat	52.2152252
    lng	5.961279500000001
    location_type	"ROOFTOP"
    viewport	
    northeast	
    lat	52.2165741802915
    lng	5.962628480291503
    southwest	
    lat	52.2138762197085
    lng	5.959930519708498
    partial_match	true
    place_id	"ChIJ8W3u5oHHx0cRJCos_cAXEok"
    types	
    0	"street_address"
    1	
    address_components	
    0	
    long_name	"123"
    short_name	"123"
    types	
    0	"street_number"
    1	
    long_name	"Hoofdstraat"
    short_name	"Hoofdstraat"
    types	
    0	"route"
    2	
    long_name	"Epe"
    short_name	"Epe"
    types	
    0	"locality"
    1	"political"
    3	
    long_name	"Epe"
    short_name	"Epe"
    types	
    0	"administrative_area_level_2"
    1	"political"
    4	
    long_name	"Gelderland"
    short_name	"GE"
    types	
    0	"administrative_area_level_1"
    1	"political"
    5	
    long_name	"Nederland"
    short_name	"NL"
    types	
    0	"country"
    1	"political"
    6	
    long_name	"8162 AD"
    short_name	"8162 AD"
    types	
    0	"postal_code"
    formatted_address	"Hoofdstraat 123, 8162 AD Epe, Nederland"
    geometry	
    location	
    lat	52.3457239
    lng	5.9841202
    location_type	"ROOFTOP"
    viewport	
    northeast	
    lat	52.3470728802915
    lng	5.985469180291502
    southwest	
    lat	52.3443749197085
    lng	5.982771219708497
    partial_match	true
    place_id	"ChIJabPXggPFx0cRDYYBrJgYPbc"
    types	
    0	"street_address"
    status	"OK"

  6. #6
    Helaas splits ie IJsselkade 57 1 in Kampen in twee adressen en ziet ie die 1 dus niet als een Bis nummer.

    https://maps.googleapis.com/maps/api...de+57+1,Kampen
    JSON Code:
    1. {
    2.    "results" : [
    3.       {
    4.          "address_components" : [
    5.             {
    6.                "long_name" : "57",
    7.                "short_name" : "57",
    8.                "types" : [ "street_number" ]
    9.             },
    10.             {
    11.                "long_name" : "IJsselkade",
    12.                "short_name" : "IJsselkade",
    13.                "types" : [ "route" ]
    14.             },
    15.             {
    16.                "long_name" : "Kampen",
    17.                "short_name" : "Kampen",
    18.                "types" : [ "locality", "political" ]
    19.             },
    20.             {
    21.                "long_name" : "Kampen",
    22.                "short_name" : "Kampen",
    23.                "types" : [ "administrative_area_level_2", "political" ]
    24.             },
    25.             {
    26.                "long_name" : "Overijssel",
    27.                "short_name" : "Overste",
    28.                "types" : [ "administrative_area_level_1", "political" ]
    29.             },
    30.             {
    31.                "long_name" : "Netherlands",
    32.                "short_name" : "NL",
    33.                "types" : [ "country", "political" ]
    34.             },
    35.             {
    36.                "long_name" : "8261 AG",
    37.                "short_name" : "8261 AG",
    38.                "types" : [ "postal_code" ]
    39.             }
    40.          ],
    41.          "formatted_address" : "IJsselkade 57, 8261 AG Kampen, Netherlands",
    42.          "geometry" : {
    43.             "location" : {
    44.                "lat" : 52.56017,
    45.                "lng" : 5.915918
    46.             },
    47.             "location_type" : "ROOFTOP",
    48.             "viewport" : {
    49.                "northeast" : {
    50.                   "lat" : 52.5615189802915,
    51.                   "lng" : 5.917266980291502
    52.                },
    53.                "southwest" : {
    54.                   "lat" : 52.5588210197085,
    55.                   "lng" : 5.914569019708497
    56.                }
    57.             }
    58.          },
    59.          "partial_match" : true,
    60.          "place_id" : "ChIJ7SZZZ4N4yEcR9nFrTQJCLdM",
    61.          "types" : [ "street_address" ]
    62.       },
    63.       {
    64.          "address_components" : [
    65.             {
    66.                "long_name" : "IJsselkade",
    67.                "short_name" : "IJsselkade",
    68.                "types" : [ "route" ]
    69.             },
    70.             {
    71.                "long_name" : "1",
    72.                "short_name" : "1",
    73.                "types" : [ "street_number" ]
    74.             },
    75.             {
    76.                "long_name" : "Kampen",
    77.                "short_name" : "Kampen",
    78.                "types" : [ "locality", "political" ]
    79.             },
    80.             {
    81.                "long_name" : "Kampen",
    82.                "short_name" : "Kampen",
    83.                "types" : [ "administrative_area_level_2", "political" ]
    84.             },
    85.             {
    86.                "long_name" : "Overijssel",
    87.                "short_name" : "Overste",
    88.                "types" : [ "administrative_area_level_1", "political" ]
    89.             },
    90.             {
    91.                "long_name" : "Netherlands",
    92.                "short_name" : "NL",
    93.                "types" : [ "country", "political" ]
    94.             },
    95.             {
    96.                "long_name" : "8261",
    97.                "short_name" : "8261",
    98.                "types" : [ "postal_code", "postal_code_prefix" ]
    99.             }
    100.          ],
    101.          "formatted_address" : "IJsselkade 1, 8261 Kampen, Netherlands",
    102.          "geometry" : {
    103.             "location" : {
    104.                "lat" : 52.555506,
    105.                "lng" : 5.9214606
    106.             },
    107.             "location_type" : "ROOFTOP",
    108.             "viewport" : {
    109.                "northeast" : {
    110.                   "lat" : 52.5568549802915,
    111.                   "lng" : 5.922809580291502
    112.                },
    113.                "southwest" : {
    114.                   "lat" : 52.55415701970851,
    115.                   "lng" : 5.920111619708497
    116.                }
    117.             }
    118.          },
    119.          "partial_match" : true,
    120.          "place_id" : "ChIJg0tG5oF4yEcRIluQWoddm6s",
    121.          "types" : [ "establishment", "point_of_interest", "premise" ]
    122.       }
    123.    ],
    124.    "status" : "OK"
    125. }

    Plein 1940 28b pakt ie dan wel weer goed. Hij laat de toevoeging niet meer zien maar dan kun je die wel weer eventueel met het echte adres uit het oorspronkelijke adres vissen. Het is wel een omslachtige methode (en ik weet niet of Google een bulk aanvraag leuk vindt) maar het werkt wel accuraat.
    Last edited by rvk; 23-Aug-17 at 22:20.

  7. #7
    Heb me een tijdje geleden redelijk verdiept in het internationale adressen probleem, omdat ik wilde uitsplitsen naar stad, provincie, staat, kanton etc. Google is naar mijn idee de beste optie, maar zeker ook niet perfect. Als je alleen Nederland wilt zou je misschien met kadaster gegevens kunnen werken.

    en ik weet niet of Google een bulk aanvraag leuk vindt
    Ja je mag volgens mij 1000 requests doen per 24 uur (sommige requests hebben trouwens wel een factor, places api dacht ik) Bij een gratis registratie wordt die limiet volgens mij 50.000 of zo. Voor mji was dat voldoende. Wil je nog meer moet je betalen, maar ook dat valt op zich wel mee.

  8. #8
    grrr, nu weer een ander geval van gekte, bij CharInSet geeft ie een foutmelding -undeclared identefier ´charinSet´- terwijl in SysUtils wel bij uses heb staan

    groet Roel

  9. #9
    Quote Originally Posted by mikafo View Post
    ... bij CharInSet geeft ie een foutmelding -undeclared identefier ´charinSet´- terwijl in SysUtils wel bij uses heb staan
    Ja, ik wist het niet helemaal zeker. Maar ik denk dat CharInSet pas in Delphi 2009 geïntroduceerd is.
    Je moet dan dus "chat in ['x', 'y']" e.d. gebruiken.

    Mijn code zou dan dit worden:

    Delphi Code:
    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3.   Adres: String = 'Plein 1940 28b';
    4.   I: Integer;
    5.   Toevoeging: String;
    6.   Nummer: String;
    7.   Straat: String;
    8. begin
    9.   I := Length(Adres);
    10.   while (I > 0) and not(Adres[I] in ['0'..'9']) do Dec(I);
    11.   Toevoeging := trim(Copy(Adres, I + 1, 255));
    12.   Adres := Copy(Adres, 1, I);
    13.   while (I > 0) and not(Adres[I] in [' ', 'A'..'z']) do Dec(I);
    14.   Nummer := trim(Copy(Adres, I + 1, 255));
    15.   Straat := trim(Copy(Adres, 1, I));
    16.   Showmessage('Straat = ' + Straat + #13 + 'Nummer = ' + Nummer + #13 + 'Toevoeging = ' + Toevoeging)
    17. end;

    In GetFirstNumPos zou je dit moeten gebruiken:
    Delphi Code:
    1. If (AAdres[I] in Numbers) Then

    (Je kunt natuurlijk op termijn ook overstappen op Lazarus. Ongeveer zelfde interface als Delphi 7 maar daar wordt de taal nog wel van doorontwikkeld )

  10. #10
    Yes, wel met een paar kleine aanpassingen(string namen), maar zonder voorzet had ik niet kunnen scoren, dus bedankt voor jouw voorzet Rik.

    zal eens kijken naar lazarus.

    Bedankt, Groet, Roel

  11. #11
    Senior Member Delphiwizard's Avatar
    Join Date
    Dec 2006
    Location
    België
    Posts
    160
    Domme vraag waarschijnlijk maar waarom precies heb je de straat en nummer apart nodig?

  12. #12
    Marius
    Join Date
    Jul 2013
    Location
    Groningen
    Posts
    178
    Wij registreren dat ook gescheiden ivm postcodeboek.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •