Zum Inhalt

Straße-Hausnummer String Permutationen zerlegen

Ich möchte hier eine kleine Funktion präsentieren, wie ich einen String der Straßennamen und Hausnummer enthält in zwei separate Strings für Hausnummer und für Straßennamen zerlege. Dabei betrachte ich nur solche Kombinationen, die ich aus Deutschland kenne.

Der ganz naive Ansatz für diese Funktion wäre den String an dem ersten Blank zu zerteilen, was in Java in etwa so aussehen könnte:

String[] result = "teststrasse 22".split("\\s");

Das resultierende Array würde in diesem Fall aus zwei Strings bestehen
1. „teststrasse“
2. „22“
Die Aufgabe wäre also hiermit erfüllt.
Leider ist der Ansatz nicht ausreichen, weil in Deutschland die Straßennamen aus zwei Wörtern bestehen können:

String[] result = "test strasse 22".split("\\s");

Das Ergebnis des Splitts wäre ein String Array mit
1. „test“
2. „strasse“
3. „22“
Wir können natürlich jetzt annehmen, dass der letzte Eintrag des Arrays immer die Hausnummer enthalten müsste. Also müssten wir jetzt die ersten beiden Strings zusammenlegen und hätten dann die gesuchten Straße und Hausnummer:

String[] result = "test strasse 22".split("\\s");
String strasse = String.join(" ", result[0], result[1]);
String hausNummer = result[2];

Wir können das Beispiel noch etwas generalisieren in dem wir den Straßennamen in eine Schleifer zusammenbauen, um den Fall abzufangen, dass der ursprüngliche String aus drei oder mehr Worten bestand. Was die Lösung oben nicht berücksichtigt:

String[] result = "test strasse 22 A".split("\\s");

oder

String[] result = "teststrasse 22 A".split("\\s");

oder

String[] result = "test strasse".split("\\s");

das ist eigentlich eine unvollständige Eingabe, die aber in Legacy System durchaus vorkommen kann.

Im folgenden Beispiel (groovy Code) geht es also am Ende nur um das Abfangen der sonderfälle:

static def street_housnr(final String hausnr_as_string) {
        def res = new HashMap<String, String>()
        res.name = ""
        res.number = ""
// die eingabe darf nicht leer sein
        if (!StringUtils.isEmpty(hausnr_as_string)) {
            def splitres = hausnr_as_string.split("\\s")
// der einfachste fall 
            if (splitres.length == 2) {
                res.put(NAME, splitres[0])
                res.put(NUMBER, splitres[1])
            }
// der fall in dem die hausnummer vergessen wurde
            if (splitres.length < 2) {
                res.put(NAME, hausnr_as_string)
                res.put(NUMBER, "")
            }
// jetzt wird es interessant
            if (splitres.length > 2) {
// der erste substring ist der anfang des straßennamens
                def street = splitres[0]
                def number = ""
// jetzt loopen wir über die restlichen arraylemente (daher i=1)
                for (int i = 1; i < splitres.length; i++) {
// der i-te string darf nicht leer sein, und wenn es mit einer zahl anfäng, dann haben wir vermutlich unsere hausnummer gefunden
                    if (splitres[i].length() > 0 && Character.isDigit(splitres[i].charAt(0))) {

// alle elemente des arrays ab index i werden in ein neues array kopiert und zu einem string zusammengefügt (hausnummer gefunden)
                        number = String.join(" ", Arrays.copyOfRange(splitres, i, splitres.length))
                        break
                    } else {
// ansonsten wird der i-te element an den strassen namen angehangen
                        street = String.join(" ", street, splitres[i])
                    }
                }
                res.put(NAME, street)
                res.put(NUMBER, number)
            }
        } else {
            res.put(NAME, hausnr_as_string)
            res.put(NUMBER, "")
        }
        return res
    }

Kurze Erläuterung warum ich Groovy Beispiel geliefert habe, obwohl ich mit Java angefangen habe: mit Groovy lässt sich manches kompakter ausdrücken.

Vermutlich habe ich mit der Funktion immer noch nicht alle Fälle für Straßennamen abgedeckt (die Eingaben durch Menschen können sehr variantenreich ausfallen)! Also freue ich mich natürlich über Straßennamen, die meine Funktion nicht zerlegen kann :-).

Published inUncategorized

Schreibe den ersten Kommentar

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

    Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.