0

我需要提取名称、街道 1、街道 2、城市、州、邮编

我有这种形式的数据

JOHN m SMITH [1111 WEST OAK ROAD, SUITE 101, CITY, ST 55555]
GEORGE m JONES [222 MAIN STREET, CITY, ST 55555]

我对 JOHN 的结果应该是

name="JOHN m SMITH"
street1="1111 WEST OAK ROAD"
street2="SUITE 101"
city = "CITY"
state = "ST"
zip = "55555"

这适用于乔治的数据

            Regex r = new Regex(@"^(?<name>.*)\[(?<street>.*)[,]\s(?<city>.*)[,]\s(?<state>.*)\s(?<zip>\d{5})\]$");
            var match = r.Match(fullNameAndAddress);
            name = match.Groups["name"].Value;
            street = match.Groups["street"].Value;
            city = match.Groups["city"].Value;
            state = match.Groups["state"].Value;
            zip = match.Groups["zip"].Value;

如何添加可选的 street2?

我想要 1 个且只有 1 个“街头”组。我认为它应该有这个:(....){1}?

street2 是可选的 0 或 1 次。我认为它应该有这个(...)?

但它不适用于 JOHN 的数据,street1 和 street2 都进入了街道组:

^(?<name>.*)\[((?<street>.*)[,]\s){1}?((?<street2>.*)[,]\s)?(?<city>.*)[,]\s(?<state>.*)\s(?<zip>\d{5})\]$
4

2 回答 2

3

你能澄清一下你想在街上存储什么吗?

你想让 John's 看起来像“1111 WEST OAK ROAD, SUITE 101”吗?

或者你想把它塞进一些你不会使用的变量中,让这条街看起来像“1111 WEST OAK ROAD”?

编辑:澄清后,请查看此链接

http://rubular.com/r/S4HaTMVFZl

我相信这里发生的事情是 * 是贪婪的,在找到 [,]\s 的最终出现之前尽可能多地抓住它

添加一个?在 .* 之后让它变得懒惰,尽可能少地获取信息。

修改后的正则表达式看起来像这样

^(?<name>.*)\[((?<street>.*?)[,]\s)((?<street2>.*)[,]\s)?(?<city>.*)[,]\s(?<state>.{2})\s(?<zip>\d{5})\]$

您会注意到我将状态的正则表达式从 .* 更改为 .{2},强制使用 2 个字符的状态。如果您不想要它,请随时恢复它:)

于 2012-09-20T02:38:26.180 回答
0

我在 rubular.com 中对您的正则表达式进行了一些更改,它似乎适用于两个示例字符串:

^(?<name>.+)\s\[(?<street>[^,]+),\s((?<street2>[^,]+),\s+)?(?<city>[^,]+),\s(?<state>.+)\s(?<zip>\d{5})\]$

street2 = match.Groups["street2"].Value;

我从正则表达式中学到的一个技巧是使用分隔符的否定(例如,[^,]* 表示除逗号之外的任何内容)而不是 .*,因此不可能用一个表达式捕获多个字段。此外,至少需要一次匹配的 + 运算符在大多数组中都很有用。

此外,仅当地址中有 street2 组件时,附加逗号才存在,这表明逗号应与 street2 部分位于同一捕获组中。我在 street2 捕获组周围添加了一个额外的捕获组来解决这个问题。您可以在大多数语言中使组不捕获,但这似乎没有必要。

于 2012-09-20T02:59:56.777 回答