正则表达式匹配街道地址

26

虽然我知道匹配街道地址永远不可能完美,但我想创建一些正则表达式语句,大多数情况下都能接近。

我试图突出显示一个地址。我很烂在正则表达式上,我尝试过了,但是有人能帮我理解如何使它更好吗?

字符串:

6 am - 11 pM , Palma Sola Elementary, 6806 Fifth Ave NW, Bradenton, FL 34209 Come find just near the dsfsd sa fsa fasdf asfsds 5001 west your momma doesn't live here my 2005 ford ranger,

正则表达式1:

/\s+(\d{2,5}\s+)(?![a|p]m\b)(([a-zA-Z|\s+]{1,5}){1,2})?([\s|\,|.]+)?(([a-zA-Z|\s+]{1,30}){1,4})(court|ct|street|st|drive|dr|lane|ln|road|rd|blvd)([\s|\,|.|\;]+)?(([a-zA-Z|\s+]{1,30}){1,2})([\s|\,|.]+)?\b(AK|AL|AR|AZ|CA|CO|CT|DC|DE|FL|GA|GU|HI|IA|ID|IL|IN|KS|KY|LA|MA|MD|ME|MI|MN|MO|MS|MT|NC|ND|NE|NH|NJ|NM|NV|NY|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VA|VI|VT|WA|WI|WV|WY)([\s|\,|.]+)?(\s+\d{5})?([\s|\,|.]+)/i

(有时只有街道和城市,没有州或邮政编码)

正则表达式2:

/\b(\d{2,5}\s+)(?![a|p]m\b)(NW|NE|SW|SE|north|south|west|east|n|e|s|w)?([\s|\,|.]+)?(([a-zA-Z|\s+]{1,30}){1,4})(court|ct|street|st|drive|dr|lane|ln|road|rd|blvd)/i

试着玩一下:http://jsfiddle.net/isuelt/rMC6P/11/


3
你没有说明你的最终目标,所以我们不知道你想要什么或者我们怎么帮助你。"让这变得更好"相当模糊。 - Willem Mulder
41
我的眼睛。我的眼睛。 - geekchic
1
欢迎来到 Stack Overflow,@isuelt -- 已经有一段时间了,别忘了通过点击勾选标记接受最有帮助的答案。 - Matt
我也发现这个很有用:https://www.codeproject.com/Tips/989012/Validate-and-Find-Addresses-with-RegEx - David
4个回答

39

美国地址并不是一种常规语言,不能使用正则表达式进行匹配。它们在某些孤立情况下可能有用,但通常情况下会让你失望,特别是对于像这样的输入。

我曾在一家地址验证公司工作。针对你的问题,“在字符串中突出显示地址”,我建议您尝试一个抽取工具。有一些可供选择,建议您四处寻找,但是这里有一个我们的抽取工具 ours,使用您问题中的输入-- 如您所见,它找到了地址并对其进行了验证:

LiveAddress extraction example

API端点返回JSON,其中包含每个地址的起始和结束位置,以及有关每个地址的大量信息(请参见上图底部的CSV输出)。我赞扬你尝试使用正则表达式!希望这对你有所帮助。

2
另一个验证想法是使用谷歌的地理编码 API 来查找他们是否有该地址的数据。 - TheTedinator
9
这是回答还是对SmartyStreets的广告? - Nick
24
@Nick这是一个回答。如果这是一则广告,我不会声明我在那里工作,并且我也不会建议他寻找其他选择。这是广告的样子:http://stackoverflow.com/a/7463590/1048862 - Matt

2

Matt说得对。正则表达式解析永远不会非常准确。如果你走这条危险的路,你不可避免地会有相当数量的误报和漏报。然而,如果你可以接受这一点,我实际上喜欢使用两个正则表达式的组合——一个用于基于街道命名的方案,另一个用于城市网格方案:

街道名称系统:

/\b\d{1,6} +.{2,25}\b(avenue|ave|court|ct|street|st|drive|dr|lane|ln|road|rd|blvd|plaza|parkway|pkwy)[.,]?(.{0,25} +\b\d{5}\b)?/ig

网格系统
/(\b( +)?\d{1,6} +(north|east|south|west|n|e|s|w)[,.]?){2}(.{0,25} +\b\d{5}\b)?\b/ig

请注意,如果地址中没有州和邮政编码,你基本上可以忘记提取街道名称之后的任何文本。


0

我需要对类似以下地址进行类似的操作:

800 SE 20 AVENUE #603, DEERFIELD BEACH

9801 NW 3 STREET APT 5, PLANTATION

11909 GLENMORE DRIVE #4-1, CORAL SPRINGS

这是我使用的正则表达式:

\s*([0-9]*)\s((NW|SW|SE|NE|S|N|E|W))?(.*)((NW|SW|SE|NE|S|N|E|W))?((#|APT|BSMT|BLDG|DEPT|FL|FRNT|HNGR|KEY|LBBY|LOT|LOWR|OFC|PH|PIER|REAR|RM|SIDE|SLIP|SPC|STOP|STE|TRLR|UNIT|UPPR|\,)[^,]*)(\,)([\s\w]*)\n

它为地址的每个部分返回单独的组(在我的情况下,我不需要解析州名)。 在此处尝试 https://regex101.com/r/OsvOxn/3


-3

这对我有效!

if(address.match(/^\s*\S+(?:\s+\S+){2}/)) {
   console.log('good address!')
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接