【问题标题】:Seperation of streetname and housenumber街道名称和门牌号码的分离
【发布时间】:2021-05-27 21:49:51
【问题描述】:

我必须从一个字符串中拆分门牌号和街道。

现在我有一个可以像这样拆分地址的工作程序:

  • 1 测试街
  • 1 条测试街
  • 1a 测试街
  • 测试街 1 号
  • Teststreet 1 a
  • 测试街 1a
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();

但这不能像这样拆分地址:

  • Teststreet 1 a-f
  • Teststreet 1a-f
  • 1 a-f Teststreet
  • 1a-f 测试街

有谁知道这是如何工作的?

感谢您的帮助。 :)

【问题讨论】:

  • 你也有剩下的地址吗?您可以使用 Google 或其他服务进行地址查找并获取地址的各个部分。否则我怀疑你会找到一个可靠的算法

标签: c# string


【解决方案1】:

在您提供的测试的简单案例中,我建议使用正则表达式以便匹配(然后提取)地址的一部分,例如街道名称,例如

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());
}

演示:

  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);

结果:

          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

【讨论】:

  • “第 12 街 123 号”?
  • @Crowcoder:这就是我所说的“在简单的情况下”:自然语言处理是复杂的事情。例如,“Palace sq. Winter Palace”
  • 我同意,这也是我说“不可靠”的原因。如果只需要解析这些情况,则不需要任何算法,只需对结果进行硬编码即可。
  • @DmitryBychenko 感谢您的解决方案。这对我来说很完美。对于地址“123 12th Street”,我会想办法的。
猜你喜欢
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多