【问题标题】:Python regex - address parsingPython 正则表达式 - 地址解析
【发布时间】:2016-12-15 09:37:22
【问题描述】:

我正在尝试解析两种类型的单行地址字符串:

Flat XXX, XXX <Building name>, <City/town>, <State> <Postcode>

DDD <Generic place name>, <Road name> road, <City/town>, <State>

使用以下正则表达式

re.search(r'(Flat \w+)?\W*(.+)\W*([a-zA-Z]{1,2}\d+\s+\d+[a-zA-Z]{1,2})?

这里XXX 是一些字母数字字符串,DDD 是一个数字。如果地址属于第一种类型,我希望第 1 组为Flat XXX,否则为None,如果地址属于第一种类型,则第 2 组为XXX &lt;Building name&gt;, &lt;City/town&gt;, &lt;State&gt;,如果属于第二种类型,我希望第 2 组为&lt;Road name&gt; road, &lt;City/town&gt;, &lt;State&gt;类型,如果地址属于第一种类型,则第 3 组为邮政编码,否则为None。邮政编码是一个英国邮政编码,我的正则表达式(不完全准确,但对我的目的来说大部分是正确的)是[a-zA-Z]{1,2}\d+\s+\d+[a-zA-Z]{1,2}。忽略大小写,Flat XXX(如果存在)和&lt;Building name&gt;之间可能没有逗号,城市和邮政编码之间可能有逗号(如果存在)。

>>> address1 = 'Flat 29, Victoria House, Redwood Lane, Richmond, London SW14 9XY'
>>> re.search(r'(Flat \w+)?\W*(.+)\W*([a-zA-Z]{1,2}\d+\s+\d+[a-zA-Z]{1,2})?', address1, re.I).groups()
>>> ('Flat 29', 'Victoria House, Redwood Lane, Richmond, London SW14 9XY', None)
>>> address2 = '91 Fleet, Major Road, Fleet, Hampshire'
>>> re.search(r'(Flat \w+)?\W*(.+)\W*([a-zA-Z]{1,2}\d+\s+\d+[a-zA-Z]{1,2})?', address2, re.I).groups()
>>> (None, '91 Fleet, Major Road, Fleet, Hampshire', None)

我不确定出了什么问题,但我认为中间群体..\W*(.+)\W*.. 或多或少地捕捉到了一切。

【问题讨论】:

  • 对,就是:regex101.com/r/uC6fiZ/1
  • 您最终需要从地址中获得什么?
  • 你有没有考虑并尝试过非贪婪版本:..\W*(.+?)\W*..
  • 我描述了我需要的内容:如果地址属于第一种类型,我希望第 1 组为Flat XXX,如果不是,则第 2 组为XXX &lt;Building name&gt;, &lt;City/town&gt;, &lt;State&gt;,如果地址为第一种类型,如果是第二种类型,则为&lt;Road name&gt; road, &lt;City/town&gt;, &lt;State&gt;,如果地址属于第一种类型,则第3组为邮政编码,否则为None
  • 非贪婪版本为我提供('Flat 29', 'V', None) 第一种地址,例如对于address1 = Flat 29, Victoria House, Redwood Lane, Richmond, London SW14 9XY

标签: python regex python-2.7 python-3.x pattern-matching


【解决方案1】:

它不是特别优雅,但这里有一个解决方法(假设&lt;State&gt; 不包含任何数字):

import re
addresses = ['Flat 29, Victoria House, Redwood Lane, Richmond, London SW14 9XY',
             '91 Fleet, Major Road, Fleet, Hampshire']

regexp = re.compile(r'(Flat \w+)?[,\s]*(.*)\s([a-zA-Z]{1,2}\d+\s?+\d+[a-zA-Z]{1,2}|\D*)$', re.I)

for address in addresses:
    sep_addr = list(re.search(regexp, address).groups())
    if not any(x.isdigit() for x in sep_addr[2]):
        sep_addr[1] +=  ' ' + sep_addr[2]
        sep_addr[2] = None
    print sep_addr

我们将第 2 组设置为邮政编码或所提供地址中的最后一个单词。然后通过检查我们第二组的结果中是否有任何数字,我们知道它是否是邮政编码。如果不是,我们追加到组 1 以提供完整的地址部分,并将组 2 设置为 None。这返回:

['Flat 29', 'Victoria House, Redwood Lane, Richmond, London', 'SW14 9XY']
[None, '91 Fleet, Major Road, Fleet, Hampshire', None]

编辑:在邮政编码中间的空格中添加了一个可选选项,以确保仍然匹配无空格的邮政编码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多