繁体   English   中英

正则表达式匹配地址与子模式

[英]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)

非正则表达式答案:查看 python 库usaddress (还有一个用于尝试的Web 界面

同意 Jim 正则表达式在这里不是一个好的解决方案。 校舍地址解析地址概率,并与凌乱的地址打交道时不止基于正则表达式的解析器强劲。

您的正则表达式在第一个字符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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM