我有一个地址类,它使用正则表达式从地址的第一行解析门牌号,街道名称和街道类型.此代码通常运行良好,但我在这里发布与社区分享,看看是否有人有改进建议.
注意: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; } } } }
Will Hartung.. 8
享受地址和正则表达式带来的乐趣,您将度过一段漫长而可怕的旅程.
你正试图在混乱中下令.
对于每一个"123简单方式",有一个"14 1/2南".
然后,为了额外的笑声,有盐湖城:"855 South 1300 East".
玩得开心.
在街头地址方面,除了规则之外还有更多例外.
享受地址和正则表达式带来的乐趣,您将度过一段漫长而可怕的旅程.
你正试图在混乱中下令.
对于每一个"123简单方式",有一个"14 1/2南".
然后,为了额外的笑声,有盐湖城:"855 South 1300 East".
玩得开心.
在街头地址方面,除了规则之外还有更多例外.
我不知道你在哪个国家,但如果你在美国并且想在地址验证上花一些钱,你可以在这里购买相关的USPS产品.而在这里是要找到从USPS的预期的词语和缩写自由单词列表的好地方.我相信其他国家/地区也可以使用类似页面.
我认为你应该澄清你的使用场景.
除非你处于一个非常非常有限的场景中,你知道地址是按照严格的模式输入的,解析内容的地址是一个非常难以解决的问题,而且通常是徒劳的(除非它是存在的理由)你的申请).
如果您仅限于某个特定国家/地区,该国家/地区具有非常具体的写入地址约定,那么使用这些正则表达式可能会让您获得90%的权限.
但是,一旦你必须开始接受外国地址,你就搞砸了.
即使您是以美国为中心的网站,您也很可能必须能够接受居住在国外的美国公民的地址.
同样,在非常狭窄的领域中可能没问题,但是在用户输入时未经严格验证和约束的地址验证或拆分地址几乎总是一个坏主意.
当你为用户输入一些严格的规则来输入他们的地址时,这些最终结果在一小部分情况下是不合适的,即使在最好的地址验证组件中也是如此.
只是搞乱地址解析的一些事情:
邮政编码(邮政编码)有时放在之前,之后,甚至根本不存在.
邮政编码遵循严格的规则:10位数的邮政编码可能很容易被发现为无效,但是不存在的邮政编码呢?那么更多的代码,例如英国使用的代码呢?
香港这样的地方怎么样用英文,繁体中文或普通话写地址?
如果分割你的地址并将其写出序列是完全正确的怎么办?
即使您只是解析美国地址,也至少有一些方法来描述邮政信箱:您也可以使用邮政餐厅,一般投递,然后需要在邮政编码中添加一个4位数代码,通常可能根本不存在......
底线是
如果以可解析的格式获取地址非常重要,请100%确定您可以正确获得所有可能的组合,否则您将失去一定比例的失败,这将意味着用户和销售损失.
如果您没有100%的案例覆盖率,则不要对用户强制执行严格的规则.
我无法计算我放弃购买的网站数量,因为当我居住的地方没有时,他们会要求邮政编码.
对于咆哮很抱歉,但我认为重要的是,想要进行地址验证和解析的人都要认真考虑自己所处的问题.