正则表达式:解析街道名称/号码

时间:2011-02-16 09:14:23

标签: c# .net regex parsing

C#/。NET 2.0

我需要在两个单独的值中解析包含街道名称和房子的字符串。

in: "Streetname 1a"         out:  "streetname"  "1a"
    "Street name 1a"              "street name" "1a"
    "Street name 1 a"             "street name" "1 a"

我的第一选择是将字符串拆分到我找到“”字符的位置,但这对第二种情况不起作用。

result[0] = trimmedInput.Substring(0, splitPosition).Trim();
result[1] = trimmedInput.Substring(splitPosition + 1).Trim();

最好的方法是什么?我可以使用正则表达式吗?

由于

5 个答案:

答案 0 :(得分:8)

^(.+)\s(\S+)$应该做的伎俩

编辑:这将工作是门牌号码不能有空格。否则这个问题不能以编程方式解决,因为程序永远不会知道字符串标记的语义。

众议院地址混乱且不一致。我使用地址数据,老实说,如果你没有标准化形式的数据,你基本上就搞砸了。

^(.+)\s(\d+(\s*[^\d\s]+)*)$将涵盖更多案例,但如果我看过一个案例那样的模式就是一堆蠕虫。

答案 1 :(得分:2)

正如Dyppl所说,街道地址很乱。但是,如果您的地址数据代表美国地址并且您拥有完整的地址(包括城市,州和/或邮政编码),您可以使用地址验证服务来解析(并验证!)并标准化组件。我为地址验证提供商SmartyStreets工作。这是一个快速的C#示例,我写了一段时间后调用我们的LiveAddress API:

https://github.com/smartystreets/LiveAddressSamples/blob/master/c-sharp/street-address.cs

以下是该示例的结果输出(请注意,街道名称和主要编号在“组件”部分中进行了解析):

[
    {
        "input_index": 0,
        "candidate_index": 0,
        "delivery_line_1": "3214 N University Ave",
        "last_line": "Provo UT 84604-4405",
        "delivery_point_barcode": "846044405140",
        "components": {
            "primary_number": "3214",
            "street_predirection": "N",
            "street_name": "University",
            "street_suffix": "Ave",
            "city_name": "Provo",
            "state_abbreviation": "UT",
            "zipcode": "84604",
            "plus4_code": "4405",
            "delivery_point": "14",
            "delivery_point_check_digit": "0"
        },
        "metadata": {
            "record_type": "S",
            "county_fips": "49049",
            "county_name": "Utah",
            "carrier_route": "C016",
            "congressional_district": "03",
            "latitude": 40.27586,
            "longitude": -111.6576,
            "precision": "Zip9"
        },
        "analysis": {
            "dpv_match_code": "Y",
            "dpv_footnotes": "AABBR1",
            "dpv_cmra": "Y",
            "dpv_vacant": "N",
            "ews_match": false
        }
    }
]

我们为低使用率的用户提供绝对免费订阅。这是一个解释所有字段的链接:

http://wiki.smartystreets.com/liveaddress_api_users_guide#json-responses

编辑:包括纬度/经度字段(新发布)。

答案 2 :(得分:1)

你必须更清楚地定义你正在寻找的模式,假设有一个模式。需要有一些一般的观察结果可以保持:

  • 街道地址由姓名和号码组成。
  • 名称始终首先出现。
  • 该名称由一个或多个单词组成,以空格分隔。
  • 该数字是一个数字,后跟一个可选字母。

从评论中,最后一点并非严格正确,因为数字&街道号码的字母部分可以用空格分隔。

如果您不能保证街道名称的顺序和数字,以及街道名称中的单词不包含数字,那么我不确定任何事情会对你有所帮助。

以下正则表达式应涵盖大多数情况:

Regex reggie = new Regex(@"^(?<name>\w[\s\w]+?)\s*(?<num>\d+\s*[a-z]?)$", RegexOptions.IgnoreCase)

答案 3 :(得分:0)

首先,您应尝试使用String.LastIndexOf()在可能的位置拆分来查找号码。

之后,您应该检查最后一组中的任何字符是否包含splittedValue.Any(c => Char.IsDigit(c));之类的任何数字。因此,如果您在最后一组中找到任何数字,您可以非常确定,您已经正确地进行了拆分,但是可能存在与此行为不匹配的地址。

更新

如果你真的有这样的嘈杂数据,必须进行规范化,我认为你不能做更好的事情,然后@Dyppl说并使用一些复杂的正则表达式,这些表达式必须通过你得到的样本进行演化。

答案 4 :(得分:0)

这假设所有“地址”将至少以上述方式之一进行格式化。

string address = "Streetname 1a"

string street = Regex.Replace(address, "^[^0-9]+", "");

string number = address.Replace(street, "");

然后修剪两个值。