[英]Regex to match address with subpatterns
我正在尝试创建一个正则表达式来将地址解析为五个部分:address1,它是街道地址,address2,它是公寓号或地址的第 2 行中显示的任何其他内容、城市、州和邮政编码代码。
当我运行它时,python(或 Django)在我运行re.search
时抛出一个错误,指出“模式意外结束”。 谁能告诉我如何修改这个正则表达式以正确匹配?
我非常喜欢正则表达式菜鸟。 我可以弄清楚这个应该做的大部分事情,但我自己永远无法写出来。 我从http://regexlib.com/REDetails.aspx?regexp_id=472得到这个。
re.compile(r"""
(?x)^(?n:
(?<address1>
(\d{1,5}(\ 1\/[234])?(\x20[A-Z]([a-z])+)+ )
| (P.O. Box \d{1,5}))\s{1,2}
(?<city>
[A-Z]([a-z])
+ (\.?)(\x20[A-Z]([a-z])+){0, 2})\, \x20
(?<state>
A[LKSZRAP] | C[AOT] | D[EC] | F[LM] | G[AU] | HI
| I[ADL N] | K[SY] | LA | M[ADEHINOPST] | N[CDEHJMVY]
| O[HKR] | P[ARW] | RI | S[CD] | T[NX] | UT | V[AIT]
| W[AIVY]
| [A-Z]([a-z])
+ (\.?)(\x20[A-Z]([a-z])+){0,2})\x20
(?<zipcode>
(?!0{5})\d{5}(-\d {4})?)
)$"
""", re.VERBOSE)
添加换行符以提高可读性。 作为一个后续问题,这个正则表达式可以像这样分成多行以提高可读性,还是需要全部在一行中才能工作(我想我可以连接单独的行)。
PS 我知道这闻起来像家庭作业,但实际上是为了工作。
编辑:请求使用的实际代码,所以在这里。 我把它省略了,因为这里的一切实际上已经在那里了,但也许它会有所帮助。
该函数是 Django 视图的一部分,但对于我们的目的来说,这并不重要。
def parseAddress(address):
pattern = r"^(?n:(?<address1>(\d{1,5}(\ 1\/[234])?(\x20[A-Z]([a-z])+)+ )|(P\.O\.\ Box\ \d{1,5}))\s{1,2}(?i:(?<address2>(((APT|APARTMENT|BLDG|BUILDING|DEPT|DEPARTMENT|FL|FLOOR|HNGR|HANGER|LOT|PIER|RM|ROOM|S(LIP|PC|T(E|OP))|TRLR|TRAILER|UNIT)\x20\w{1,5})|(BSMT|BASEMENT|FRNT|FRONT|LBBY|LOBBY|LOWR|LOWER|OFC|OFFICE|PH|REAR|SIDE|UPPR|UPPER)\.?)\s{1,2})?)(?<city>[A-Z]([a-z])+(\.?)(\x20[A-Z]([a-z])+){0,2})\, \x20(?<state>A[LKSZRAP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADL N]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD] |T[NX]|UT|V[AIT]|W[AIVY]|[A-Z]([a-z])+(\.?)(\x20[A-Z]([a-z])+){0,2})\x20(?<zipcode>(?!0{5})\d{5}(-\d {4})?))$"
match = re.search(pattern, address)
我使用我的家庭地址作为输入,但我也尝试了“123 Main St., Austin, TX 12345”作为输入,结果相同。
有些人可能不认为这是一个答案,但请耐心等待。
我强烈建议反对尝试使用正则表达式解析街道地址。 街道地址在任何意义上都不是“常规”的。 有无限的变化,除非你将自己限制在一个非常有限的语法上,否则总会有你无法解析的字符串。 大量的时间和金钱已投入到解析地址的解决方案上,首先是美国邮局和许多列表清理服务提供商。 只需谷歌“解析街道地址”即可获得问题范围的提示。 有商业解决方案和一些免费解决方案,但网络上的评论表明没有人总是能做到正确。
我也是经验之谈。 80 年代,我在一家数据库排版公司工作,我们不得不解析地址。 我们始终无法开发出完美运行的解决方案,对于我们自己捕获的数据(我们有一个庞大的键盘部门),我们开发了一种特殊的符号语法,以便操作员可以在适当的位置插入分隔符以帮助解析过程。
看看那里的一些免费服务。 你会省去很多麻烦。
在正则表达式中设置x
(详细)标志,即: (?x)
您的正则表达式在第一个字符n
上失败,您可以按如下方式验证。 创建一个文件test.py
并输入以下内容:
import re
re.compile(r'...')
当然,您可以在其中填写您的模式:) 现在运行python -m pdb test.py
,输入c
继续,它会在引发异常时停止。 此时键入l
以查看您在代码中的位置。 您会看到它失败,因为source.next
不在FLAGS
。 这个source
只是你的模式,所以你可以通过输入print source.index
来验证它在哪里失败。
此外,删除前面的 n,该模式在<address1>
的第a
处失败。
(?n
很奇怪,我在文档中找不到它,所以它似乎是不受支持的扩展。至于?<address1>
,我认为这应该是?P<address1>
。还有更多问题它,比如(?i:
如果我删除它们并修复?P<
内容,我会在最后一个括号中收到有关不平衡括号的错误。
Jim Garrison(上图)是正确的 - 地址变化太大,无法使用正则表达式进行解析。 我在一家地址验证软件公司工作——SmartyStreets 。 试试我们的LiveAddress API - REST 端点提供所有地址组件,解析为一个漂亮、易于使用的 JSON 响应。 这是一个示例:
https://github.com/smartystreets/LiveAddressSamples/blob/master/python/street-address.py
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.