用于解析邮件地址的正则表达式

我有一个地址类,它使用正则表达式来解析地址第一行的门牌号,街道名称和街道类型。 此代码通常运行良好,但我在这里发布与社区分享,看看是否有人有改进建议。

注意:STREETTYPES和QUADRANT常量分别包含所有相关的街道类型和象限。

我在这里包含了一个子集:

private const string STREETTYPES = @"ALLEY|ALY|ANNEX|AX|ARCADE|ARC|AVENUE|AV|AVE|BAYOU|BYU|BEACH|..."; private const string QUADRANTS = "N|NORTH|S|SOUTH|E|EAST|W|WEST|NE|NORTHEAST|NW|NORTHWEST|SE|SOUTHEAST|SW|SOUTHWEST"; 

HouseNumber,Quadrant,StreetName和StreetType都是该类的所有属性。

  private void Parse(string line1) { HouseNumber = string.Empty; Quadrant = string.Empty; StreetName = string.Empty; StreetType = string.Empty; if (!String.IsNullOrEmpty(line1)) { string noPeriodsLine1 = String.Copy(line1); noPeriodsLine1 = noPeriodsLine1.Replace(".", ""); string addressParseRegEx = @"(?ix) ^ \s* (?: (?\d+) (?:(?:\s+|-)(?" + QUADRANTS + @"))? (?:(?:\s+|-)(?\S+(?:\s+\S+)*?))?? (?:(?:\s+|-)(?" + QUADRANTS + @"))? (?:(?:\s+|-)(?" + STREETTYPES + @"))? (?:(?:\s+|-)(?(?!(?:" + QUADRANTS + @"))(?:\d+|\S+)))? (?:(?:\s+|-)(?(" + QUADRANTS + @")))?? (?:(?:\s+|-)(?(?:ste|suite|po\sbox|apt)\s*\S*))? | (?:(?:po|postoffice|post\s+office)\s+box\s+(?\S+)) ) \s* $ "; Match match = Regex.Match(noPeriodsLine1, addressParseRegEx); if (match.Success) { HouseNumber = match.Groups["housenumber"].Value; Quadrant = (string.IsNullOrEmpty(match.Groups["quadrant"].Value)) ? match.Groups["streettypequadrant"].Value : match.Groups["quadrant"].Value; if (match.Groups["streetname"].Captures.Count > 1) { foreach (Capture capture in match.Groups["streetname"].Captures) { StreetName += capture.Value + " "; } StreetName = StreetName.Trim(); } else { StreetName = (string.IsNullOrEmpty(match.Groups["streetname"].Value)) ? match.Groups["streettypequalifier"].Value : match.Groups["streetname"].Value; } StreetType = match.Groups["streettype"].Value; //if the matched street type is found //use the abbreviated version...especially for credit bureau calls string streetTypeAbbreviation; if (StreetTypes.TryGetValue(StreetType.ToUpper(), out streetTypeAbbreviation)) { StreetType = streetTypeAbbreviation; } } } } 

我不知道你在哪个国家,但如果你在美国并且想在地址validation上花一些钱,你可以在这里购买相关的USPS产品。 这里是一个从USPS找到预期单词和缩写的免费单词列表的好地方。 我相信其他国家/地区也可以使用类似页面。

享受地址和正则表达式带来的乐趣,让您度过漫长而可怕的旅程。

你正试图在混乱中下令。

对于每一个“123简单方式”,都有一个“14 1/2南”。

然后,为了额外的笑声,盐湖城:“855 South 1300 East”。

玩得开心。

在街头地址方面,除了规则之外还有更多的例外情况。

我认为你应该澄清你的使用场景。

除非你处于一个非常非常有限的场景中,你知道地址是按照严格的模式输入的,解析内容的地址是一个非常难以解决的问题,而且通常是徒劳的(除非它是存在的理由 )你的申请)。

如果您仅限于某个具有非常具体的写地址约定的国家/地区,那么使用这些正则表达式可能会让您获得90%的权限。
但是,一旦你必须开始接受外国地址,你就搞砸了。
即使您是以美国为中心的网站,您也很可能必须能够接受居住在国外的美国公民的地址。

同样,在非常狭窄的领域中可能没问题,但是在用户输入时未经严格validation和约束的地址validation或拆分几乎总是一个坏主意。
当你为用户强制执行一些严格的规则来输入他们的地址时,这些结果在一小部分情况下是不够的,即使在最好的地址validation组件中也是如此。

只是一些搞乱地址解析的东西:

  • 邮政编码(邮政编码)有时放在之前,之后,甚至根本不存在。
  • 邮政编码遵循严格的规则:一个10位数的邮政编码可能很容易被发现为无效,但是一个不存在的邮政编码呢? 那么更多的代码如英国使用的代码呢?
  • 香港这样的地方怎么样用英文,繁体中文或普通话写地址?
  • 如果分割你的地址并将其写出顺序完全没问题怎么办?
  • 即使您只是解析美国地址,至少有一些方法来描述邮政信箱:您也可以使用邮政餐厅一般投递 ,然后需要在邮政编码中添加一个4位数代码,通常可能根本不存在……

底线是

如果以可解析的格式获取地址非常重要,请100%确定您可以正确获得所有可能的组合,否则您将失去一定比例的失败,这将意味着用户和销售损失。
如果您没有100%的案例覆盖率,则不要对用户强制执行严格的规则。
我无法计算我放弃购买的网站数量,因为当我居住的地方没有时,他们会要求邮政编码。

对于咆哮很抱歉,但我认为重要的是,想要进行地址validation和解析的人会认真考虑他们自己所处的内容。

这实际上工作得很好,除了它不拉公寓号码。 我们正在努力。 当我们有一个769 Branch Ave的地址时,它也有点咳嗽。 当然,“分支”是其寻找的街道类型之一。 这一切都可以追溯到混乱的事情。 我们知道它会在这里和那里打破。

如果有人在2013/2014遇到此问题:)您可以使用谷歌地理编码API。 它提供的function不仅仅是正则表达式 – 你甚至可以获得lat / long地址。 它是免费的

对于地址示例 –

http://maps.googleapis.com/maps/api/geocode/xml?address=2520%20Cohasset%20Rd%20-%20Chico%2C%20CA%2095973-1307%20530-893-1300%20%20&sensor=false

在此处输入图像描述

我试图让它工作,但似乎你有一个StreetTypes类的静态成员,不包括在内。 它似乎除了那之外有用,但没有它我就做不了多少测试。

我同意你的严格要成为一个问题。 我正在编写一个地址解析器,旨在从分类广告中剥离地址,其格式可以是任何东西。 例如,对于您的象限匹配,您完全忽略了标点符号。 我必须以所有这些不同的方式搜索可能代表NE的数据:

“NE”,“NE”,“NE”,“NE”,“N.E”,“North East”,“Northeast”

所以我使用以下模式匹配,无论表达方式如何,都应该捕获所有方向限定符:

 \b(?:(?:[nesw]\.? ?){0,2}|(?:north|no\.|east|south|so\.|west){0,2})\b 

当然,背景也很重要,因为“不”将与此相匹配。 但是内布拉斯加州的“NE”将与之相匹配,所以你必须要小心你的大表达中左右两边的内容。 我必须编译通常出现在地址文本中的单词列表,这些单词不是地址组件,例如“near,x-street,in,across”等。

这是一个非常棘手的问题,我同意盐湖城是一个婊子。 除了具有双向/坐标格式之外,它们还通过引用诸如“3700 North 5300 East Arborville Way”之类的东西来复合它,其中街道可以通过名称,数字或两者来引用。