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

hc8w905p  于 2023-06-25  发布在  其他
关注(0)|答案(5)|浏览(108)

C#/.NET 2.0
我需要解析一个字符串,其中包含街道名称和门牌号两个单独的值。

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

我的第一个选择是在找到““char的地方拆分字符串,但这对第二种情况不起作用。

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

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

p4tfgftt

p4tfgftt1#

^(.+)\s(\S+)$应该可以
编辑:这将工作是门牌号不能有空格。否则,这个问题无法通过编程解决,因为程序永远不会知道字符串标记的语义。
家庭住址混乱且不一致。我处理过地址数据,老实说,如果你没有规范化的数据,你基本上就完蛋了。
^(.+)\s(\d+(\s*[^\d\s]+)*)$将涵盖更多的情况,但像这样的模式是一罐蠕虫,如果我见过一个。

smtd7mpg

smtd7mpg2#

你必须更清楚地定义你正在寻找的模式,假设甚至有一个。需要有一些你可以做的一般性观察,这些观察将永远保持不变:

  • 街道地址由名字和号码组成。
  • 名字总是出现在最前面。
  • 名称由一个或多个单词组成,单词之间用空格分隔。
  • 数字是一个数字,后面跟着一个可选的字母。

从评论来看,最后一点并不严格正确,因为街道号码的数字和字母部分可以用空格分隔。
如果你不能保证街道名称和数字的顺序,而且街道名称中的单词不包含数字,那么我真的不确定有什么能帮助你。
下面的正则表达式应该涵盖大多数情况:

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

x6yk4ghg3#

正如Dyppl所说,街道地址是混乱的。但是,如果您的地址数据代表美国地址,并且您有完整的地址(包括城市、州和/或邮政编码),则可以使用地址验证服务来解析(并验证!)并对组件进行标准化。我为SmartyStreets工作,这是一家地址验证提供商。这是我不久前写的一个快速C#示例,它调用了我们的LiveAddress API:
https://github.com/smartystreets/LiveAddressSamples/blob/master/c-sharp/street-address.cs
以下是该示例的结果输出(注意,街道名称和主要号码在“components”部分中进行了解析):

[
    {
        "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
编辑:包括纬度/经度字段(新发布)。

u0njafvf

u0njafvf4#

首先,您应该尝试通过使用String.LastIndexOf()在可能的位置分割来找到数字。
然后,您应该检查最后一组中是否有任何字符包含任何数字,如splittedValue.Any(c => Char.IsDigit(c));。因此,如果您在最后一组中找到任何数字,您可以非常肯定,您的拆分是正确的,但可能存在与此行为不匹配的地址。

更新

如果你真的有这样的噪声数据,必须规范化,我认为你不能做任何更好的,然后@Dyppl说,并使用一些复杂的正则表达式,必须演变的样本,你得到的,这将不会工作。

2wnc66cl

2wnc66cl5#

这是假设你所有的“地址”将被格式化在至少一个上述的方式。

string address = "Streetname 1a"

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

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

然后修剪这两个值。

相关问题