LarsA
LarsA

Reputation: 13

Seperation of streetname and housenumber

I have to split housenumbers and streets from a string.

Right now i have a working program which can split adresses like this:

string street = Teststreet 1;
string houseNr = "";

for (int k = 0; k < street.Length; k++)
{
  (Char.IsNumber(street[k]) == true)
  {
     houseNr += street[k].ToString();
  }

  if (k + 1 < street.Length && k + 2 == street.Length - 1)
  {
     if (!string.IsNullOrEmpty(houseNr) && street[k + 1] == ' ')
     {
       houseNr +=' ' + street[k + 2].ToString();
     }
  }

  if (k + 2 < street.Length && !string.IsNullOrEmpty(houseNr) && Char.IsLetter(street[k + 1]) && street[k+2]==' ' && Char.IsNumber(street[k])
                                    || k + 1 < street.Length && k + 2 == street.Length - 1 && !string.IsNullOrEmpty(houseNr) && Char.IsLetter(street[k + 1]) && Char.IsNumber(street[k])
                                    || k + 1 < street.Length && k + 2 == street.Length - 1 && !string.IsNullOrEmpty(houseNr) && street[k + 1] == ' ' && Char.IsNumber(street[k])
                                    || k + 1 == street.Length - 1  && !string.IsNullOrEmpty(houseNr) && Char.IsLetter(street[k + 1]) && Char.IsNumber(street[k]))
  {
      houseNr += street[k + 1].ToString();
  }
  if (k + 3 < street.Length)
  {
      if (street[k + 1] == ' ' && street[k + 3] == ' ')
      {
         houseNr += ' ' + street[k + 2].ToString();
      }
  }
}
street = street.Replace(houseNr.Trim(), "").Trim();

But this can´t split adresses like this:

Does anyone have a idea how this could work?

Thanks for your help. :)

Upvotes: 1

Views: 135

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186688

In the simple case for the test you've provided, I suggest using regular expressions in order to match (and then extract) the part of the address, say, the street name, e.g.

using System.Text.RegularExpressions;

...

private static (string street, string number) SplitStreet(string value) {
  var match = Regex.Match(value, @"\p{L}{2,}(?:\s\p{L}+)*");

  string street = match.Value;

  string number = (match.Index > 0)
    ? value.Substring(0, match.Index)
    : value.Substring(match.Index + match.Length);

  return (street, number.Trim());
}

Demo:

  string[] tests = new string[] {
    "1 Teststreet",
    "1 a Teststreet",
    "1a Teststreet",
    "Teststreet 1",
    "Teststreet 1 a",
    "Teststreet 1a",
    "Teststreet 1 a-f",
    "Teststreet 1a-f",
    "1 a-f Teststreet",
    "1a-f Teststreet",
    "King George V 3a(1)",
    "3a(1) King George V",
    "Невский проспект 15a/4", // a bit of Russian
  };

  string result = string.Join(Environment.NewLine, tests
    .Select(test => new { 
      raw = test,
      address = SplitStreet(test)
    })
    .Select(test=> $"{test.raw,25} -> {test.address.street} :: {test.address.number}")) ;

  Console.Write(result);

Outcome:

          1 Teststreet -> Teststreet :: 1
        1 a Teststreet -> Teststreet :: 1 a
         1a Teststreet -> Teststreet :: 1a
          Teststreet 1 -> Teststreet :: 1
        Teststreet 1 a -> Teststreet :: 1 a
         Teststreet 1a -> Teststreet :: 1a
      Teststreet 1 a-f -> Teststreet :: 1 a-f
       Teststreet 1a-f -> Teststreet :: 1a-f
      1 a-f Teststreet -> Teststreet :: 1 a-f
       1a-f Teststreet -> Teststreet :: 1a-f
   King George V 3a(1) -> King George V :: 3a(1)
   3a(1) King George V -> King George V :: 3a(1)
Невский проспект 15a/4 -> Невский проспект :: 15a/4

Upvotes: 1

Related Questions