如何使用正则表达式提取带有可选street2的地址

时间:2012-09-20 02:29:47

标签: regex

我需要提取名称,街道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"

这适用于GEORGE的数据

            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是可选的零或1次。我以为它应该有这个(...)?

但它不适用于JOHN的数据,包括street1和amp; street2正在进入街道小组:

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

2 个答案:

答案 0 :(得分:3)

你能澄清一下你想要存放在街上的东西吗?

你想让约翰看起来像'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个字符的状态。如果你不想要它,请随意回复:)

答案 1 :(得分:0)

我在rubular.com中对你的正则表达式进行了一些更改,它似乎正在处理示例字符串:

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

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

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

另外,只有当地址的street2组件存在时,附加逗号才会出现,这表示逗号应与street2部分位于同一个捕获组中。我在street2捕获组周围添加了一个额外的捕获组来解释这个问题。你可以在大多数语言中使用非捕获组,但似乎没必要。