Hoi,

Ik heb een grote lijst met adressen en telefoonnummers. Die lijst wil ik netjes verwerken en in een mysql database stoppen. Het lastige is dat er een aantal verschillende formaten zijn waarin de adressen worden weergeven. Ik dacht dat ik er met regular expressions uit zou komen, maar mijn kennis daarvan is niet groot genoeg. Graag krijg ik hier wat hulp bij.

Dit zijn de straatformaten:

Rodekruislaan 23
2e Rodekruislaan 23
2e Rode Kruislaan 23
Rodekruislaan 23 B
2e Rodekruislaan 23 B
2e Rode Kruis Laan 23 B
Rodekruislaan 23/C
2e Rodekruislaan 23/C
Rodekruislaan 23C 001
2e Rodekruislaan 23C 001
Rodekruislaan 23 C 001
Rodekruislaan 23 C 001B
etc

Ik wil graag de straat, het nummer en de toevoeging opsplitsen. Tot nu toe heb ik dit:
<?php
if (preg_match('/(?P<straat>.*)\s(?P<nummer>\d*)\s(?P<toevoeging>\w*)$/', $string, $matches)) {

var_dump($matches);

}
?>

Ik krijg dan de volgende array terug:

array (size=8)
0 => string 'Rode Kruislaan 1302' (length=19)
'straat' => string 'Rode Kruislaan' (length=14)
1 => string 'Rode Kruislaan' (length=14)
'nummer' => string '130' (length=3)
2 => string '130' (length=3)
3 => string '2' (length=1)
'toevoeging' => string '' (length=0)
4 => string '' (length=0)

Ik snap niet waarom het nummer afgebroken wordt. Kan iemand mij dat vertellen? En weet jij of er een formaat is waarmee ik alle typen adressen kan formateren? Het kan dus zijn dat een straatnaam meerdere spaties heeft, wat het ook lastig maakt, denk ik. Ook kan het zijn dat de string begint met een nummer, zoals je ziet in de voorbeelden hier bovven.

Alvast super bedankt, ik weet dat dit een lastige vraag is.

Groetjes,

Arthur
Grappig, hoe ga je adressen als Laan 1940-1945 12 dan goed oppakken? Dit soort dingen leidt *altijd* tot gezeur, laat mensen gewoon zelf hun adres invullen zoals het hoort. Dus met gewoon velden voor straat, huisnummer etc. Mensen weten veel beter waar ze wonen dan wat jij denkt ervan te kunnen maken.
Beste Ben,

Het gaat om een lijst die ik al heb, dus niet om data die ik nog moet verzamelen.

Toevoeging op 06/09/2016 20:10:24:

Daarnaast weet ik dat er altijd uitzonderingen zullen zijn. In het geval van Laan 1945 zal ik gewoon handmatig een aanpassing moeten doen en dat vind ik niet zo erg. Maar ik wil graag dat het bulk van de straatnamen goed geformateerd worden en daarbij kan ik hulp gebruiken. Ik stel hulp dan ook zeer op prijs.
Dit moet je een eind op weg helpen.

<?php

echo '<h3>Array</h3>';

$haystack = array("Rodekruislaan 23",
"2e Rodekruislaan 23",
"2e Rode Kruislaan 23",
"Rodekruislaan 23 B",
"2e Rodekruislaan 23 B",
"2e Rode Kruis Laan 23 B",
"Rodekruislaan 23/C",
"2e Rodekruislaan 23/C",
"Rodekruislaan 23C 001",
"2e Rodekruislaan 23C 001",
"Rodekruislaan 23 C 001",
"Rodekruislaan 23 C 001B");

echo '<pre>';
print_r($haystack);
echo '</pre>';

echo '<h3>Output Array na preg_match</h3>';

$output = array();

for($x = 0; $x < count($haystack); $x++) {

	preg_match("/^(.+)\s(\d+)\s?(.?)(.*)?/", $haystack[$x], $output_array);

	if(count($output_array) > 0) {
		$output[] = $output_array;
	}

}

echo '<pre>';
print_r($output);
echo '</pre>';

echo '<h3>Netjes geprint</h3>';

for($i = 0; $i < count($output); $i++) {
	for($x = 0; $x < count($output[$i]); $x++) {
		echo ' {' . $output[$i][$x] . '} ';
	}
	echo "<br>";
}

?>
Wauw adoptive solutions! Dat lijkt al een heel eind in de goede richting. Toch gaat het nog niet helemaal goed. Bij de laatste vier worden de huisnummers niet gescheiden. Is daar nog een oplossing voor te vinden? Hartelijk bedankt, ik ben hier al heel blij mee, je helpt me echt enorm!

Toevoeging op 06/09/2016 23:11:42:

"Netjes geprint" wordt het zo weergegeven:

{Rodekruislaan 23} {Rodekruislaan} {23} {} {}
{2e Rodekruislaan 23} {2e Rodekruislaan} {23} {} {}
{2e Rode Kruislaan 23} {2e Rode Kruislaan} {23} {} {}
{Rodekruislaan 23 B} {Rodekruislaan} {23} {B} {}
{2e Rodekruislaan 23 B} {2e Rodekruislaan} {23} {B} {}
{2e Rode Kruis Laan 23 B} {2e Rode Kruis Laan} {23} {B} {}
{Rodekruislaan 23/C} {Rodekruislaan} {23} {/} {C}
{2e Rodekruislaan 23/C} {2e Rodekruislaan} {23} {/} {C}
{Rodekruislaan 23C 001} {Rodekruislaan 23C} {001} {} {}
{2e Rodekruislaan 23C 001} {2e Rodekruislaan 23C} {001} {} {}
{Rodekruislaan 23 C 001} {Rodekruislaan 23 C} {001} {} {}
{Rodekruislaan 23 C 001B} {Rodekruislaan 23 C} {001} {B} {}

Toevoeging op 06/09/2016 23:13:56:

Nog een vraag; ik snap niet goed waarvoor de vraagtekens gebruikt worden, bijvoorbeeld: \s?. Kun je me dat vertellen, want in de documentatie kom ik er niet echt uit.
Introduceer eerst een fout met zoek vervang en maak van 23C en 23 C > 23/C

Dan wordt het netjes gesplits.

EDIT : te vroeg gegokt, dan maar met de hand wijzigen.

\s? kijkt of er een spatie is.

Hoi Adoptive Solution. Wat bedoel je met 'introduceer eerst een fout'? En misschien een stomme vraag, hoe voeg ik die slash toe, wanneer we het punt bereiken waarop we als straat Rodekruislaan 23 C krijgen, is de code al uitgevoerd. Kun je me hier nog mee helpen? Ik ben er ondertussen wel mee aan 't stoeien. Ik kan nadat de code is uitgevoerd wel een str_replace doen, maar dan is het nog niet gescheiden?

Toevoeging op 06/09/2016 23:50:04:

Ik volg je niet helemaal, wat bedoel je met 'te vroeg gegokt'? Ik kan de records niet echt met de hand wijzigen, ik heb 2 miljoen records die geformateerd moeten worden.
Ik weet niet hoeveel straatnamen er zijn, maar haal eerst de goede adressen eruit en corrigeer de rest met de hand.

Toevoeging op 07/09/2016 00:18:40:

Verwijder met zoek/vervang de spaties en / uit de huisnummers en gebruik dan dit :

preg_match("/^(.+)\s(\d+)\s?(.?)\s?(.*)?/", $haystack[$x], $output_array);


Het resultaat is dan beter.

Je moet dan alleen nog bv. 001B met de hand splitsen.
ik zou een oplossing met een regex alleen loslaten op een adres met hooguit 1 getal (getal, dus niet cijfer) erin.

En dan ga ik er nog vanuit dat er ook werkelijk een huisnummer in je adres staat.

Alles wat je overhoudt:
plein 1940 12
Willem 3 laan 13
1e kerkstraat 3
kerkstraat 42F1

laat je door een stagiair oplossen.
Deze oplossing in JavaScript is wel aardig:

https://gist.github.com/devotis/c574beaf73adcfd74997

Maar ik denk dat ik zelf een andere 'oplossingsstrategie' zou volgen. Voor Nederlandse adressen gelden enkele beperkingen: het huisnummer en de huisnummertoevoeging mogen beide niet langer zijn dan 5 karakters. Inclusief scheidingsteken tussen huisnummer en huisnummertoevoeging kom je daarmee op maximaal 11 karakters vanaf het einde van de adresregel. Die regels zijn het uitgangspunt van de volgende functie:


<?php
/**
 * @param string $address
 * @return array
 */
function getAddressArray($address)
{
    $address = trim($address);
    $street = $address;
    $home_number_extension = '';
 
    $home_number = substr($address, -11);
    $max = strlen($home_number);

    for ($i=0; $i < $max; $i++) {
        if (is_numeric($home_number{$i})) {
            $home_number = substr($address, -$max + $i);
            $street = substr($address, 0, strlen($address) - $max + $i);
            break;
        }
    }

    if ($i == $max) {
        $home_number = '';
        $home_number_extension = '';
    }

    for ($i = 0; $i < strlen($home_number); $i++) {
        if (!is_numeric($home_number{$i})) {
            $home_number_extension = substr($home_number, $i);
            $home_number = substr($home_number, 0, $i);
            break;
        }
    }

    return array(trim($street), trim($home_number), trim($home_number_extension));
}

// Test cases
$cases = array(
    'Rodekruislaan 23',
    '2e Rodekruislaan 23',
    '2e Rode Kruislaan 23',
    'Rodekruislaan 23 B',
    '2e Rodekruislaan 23 B',
    '2e Rode Kruis Laan 23 B',
    'Rodekruislaan 23/C',
    '2e Rodekruislaan 23/C',
    'Rodekruislaan 23C 001',
    '2e Rodekruislaan 23C 001',
    'Rodekruislaan 23 C 001',
    'Rodekruislaan 23 C 001B',
);

// Test
echo '<pre>';
foreach ($cases as $case) {
    var_dump($case);
    var_dump(getAddressArray($case));
}
?>
In Ede is een "Laan 1933"

Woon je daar op nummer 12, dan verhuist bovenstaand script je naar huisnummer 1933 met toevoeging 12.

Misschien zou het nog een optie zijn om op basis van de postcode via een API een straatnaam erbij te zoeken voor de twijfelgevallen.
Met een beetje geluk matcht de gevonden straatnaam ook met de schrijfwijze van het adres in je lijst.

Maar met "BURG. WUITEWEG" vs "Burgemeester Wuiteweg" heb je evengoed nog een uitdaging.

Reageren