【问题标题】:Regex to group Zip Code , City and State正则表达式对 Zip Code 、 City 和 State 进行分组
【发布时间】:2016-04-19 05:11:59
【问题描述】:

我有以下字符串

“98225-2077 贝灵厄姆 WA”

我需要使用正则表达式来分隔邮政编码、城市和州。 团体应该返回 (98225-2077)(贝灵厄姆)和(西澳)。 State 是可选的,并且始终位于末尾,由两个大写字符组成。

我可以使用正则表达式过滤掉以下内容

邮政编码:(^([\S]+-)?\d+(-\d+)?) - 组[1]
城市:((^([\S]+-)?\d+(-\d+)?)\s)?(\S.*) = 组[5]。

是否可以有一个正则表达式使用相同的正则表达式过滤掉所有三个并在状态不存在的情况下返回空白?

【问题讨论】:

  • 城市名称也可以是多个单词。例如新德里。
  • 太好了...谢谢你现在告诉我这个
  • 唯一的解析方式是正则表达式,根据设计存储在数据库中
  • 不为“98225-2077 Bellingham”分组。请将其发布在答案部分,以便我将其标记为答案

标签: c# regex


【解决方案1】:

我会选择只在空间上拆分字符串,然后根据需要使用各个部分。因为您的城市名称可能由多个单词组成,所以我从倒数第二个元素迭代来构建城市名称。此解决方案假定邮政编码和州两个缩写始终是单个单词。

string address = "98225-2077 Bellingham WA";
string[] tokens = address.Split(' ');

string city = "";
for (int i=1; i < tokens.Length-1; i++)
{
    if (i > 1)
    {
        city += " ";
    }
    city += tokens[i];
}

Console.WriteLine("zip code: {0}", tokens[0]);
Console.WriteLine("city: {0}", city);
Console.WriteLine("state: {0}", tokens[tokens.Length-1]);

【讨论】:

    【解决方案2】:

    简单!

    ^([\d-]+)\s+(.+?)\s*([A-Z]{2})?$
    

    https://regex101.com/r/tL4tN5/1

    解释:

    1. ^([\d-]+):^ 是字符串的开头。 \d 表示数字
    2. \s+(.+?)\s*: 在邮政编码和州之间获取任何东西
    3. ([A-Z]{2})?$:{2} 表示指定范围[A-Z] 中的2 个字符。 ? 表示存在 1 次或 0 次。

    【讨论】:

    • 状态可以存在或不存在。我正在使用 c#
    • 是的,它可以在没有状态的情况下工作。我稍微更新了正则表达式以更准确。请查看
    【解决方案3】:

    这也可以

    ^(\d[\d-]+)\s+(.*?)(?:\s+([A-Z]{2}))?$
    

    Regex Demo

    Ideone Demo

    【讨论】:

      【解决方案4】:

      我真的认为你可以在没有正则表达式的情况下做到这一点。这里有两个解决方案:

      非正则表达式解决方案:

      /// <summary>
      /// Split address into ZIP, Description/Street/anything, [A-Z]{2} state
      /// </summary>
      /// <returns>null if no space is found</returns>
      public static List<string> SplitZipAnyStateAddress(this string s)
      {
          if (!s.Contains(' ')) return null;
          var zip = s.Substring(0, s.IndexOf(' '));
          var state = s.Substring(s.LastIndexOf(' ') + 1);
          var middle = s.Substring(zip.Length + 1, s.Length - state.Length - zip.Length - 2);
          return state.Length == 2 && state.All(p => Char.IsUpper(p)) ? 
              new List<string>() { zip, middle, state } : 
              new List<string>() { zip, string.Format("{0} {1}", middle, state) };
      }
      

      结果:

      StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellingham WA");
      // => [0] 98225-2077 [1] Bellingham [2] WA
      StringRegUtils.SplitZipAnyStateAddress("98225-2077 Bellin gham");
      // => [0] 98225-2077 [1] Bellin gham
      StringRegUtils.SplitZipAnyStateAddress("98225-2077 New Delhi CA");
      // => [0] 98225-2077 [1] New Delhi [2] CA
      

      正则表达式

      如果没有,您可以使用我最初的正则表达式建议(我认为 ? 迷路了):

      ^(?<zip>\d+-\d+)\s+(?<city>.*?)(?:\s+(?<state>[A-Z]{2}))?$
      

      见regex demo

      详情:

      • ^ - 字符串开头
      • (?&lt;zip&gt;\d+-\d+) - 1+ 位后跟 - 后跟 1+ 位
      • \s+ - 1+ 个空格
      • (?&lt;city&gt;.*?) - 除了换行符之外的 0+ 个字符尽可能少到
      • (?:\s+(?&lt;state&gt;[A-Z]{2}))? - 可选(1 或 0)次
        • \s+ - 1+ 个空格
        • (?&lt;state&gt;[A-Z]{2}) - 正好 2 个大写 ASCII 字母
      • $ - 字符串结束

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-09
        • 1970-01-01
        • 1970-01-01
        • 2020-02-20
        相关资源
        最近更新 更多