【问题标题】:Extract different formats street address from a string using RE - Python使用 RE - Python 从字符串中提取不同格式的街道地址
【发布时间】:2018-08-10 04:30:26
【问题描述】:

我有不同格式的街道地址字符串。我试过这个旧的post,但没有多大帮助。我的字符串格式如下,

格式 1:

string_1 = ', landlord and tenant entered into a an agreement with respect to approximately 5,569 square feet of space in the building known as "the company" located at 788 e.7th street, st. louis, missouri 55605 ( capitalized terms used herein and not otherwise defined herein shall have the respective meanings given to them in the agreement); whereas, the term of the agreement expires on may 30, 2015;'

想要的输出:

788 e.7th street, st. louis, missouri 55605

格式 2:

string_2 = 'first floor 824 6th avenue, chicago, il where the office is located'

想要的输出:

824 6th avenue, chicago, il

格式 3:

string_3 = 'whose address is 90 south seventh street, suite 5400, dubuque, iowa, 55402.'

想要的输出:

90 south seventh street, suite 5400, dubuque, iowa, 55402

到目前为止,我试过了,这是string_1

address_match_1 = re.findall(r'((\d*)\s+(\d{1,2})(th|nd|rd).*\s([a-z]))', string_1)

我得到一个空列表。

对于第二个字符串,我尝试了相同的方法并得到如下的空列表,

address_match_2 = re.findall(r'((\d*)\s+(\d{1,2})(th|nd|rd).*\s([a-z]))', string_2)

如何尝试使用 re 进行匹配?它们都是不同的格式,我怎样才能让套件参与string_3?任何帮助将不胜感激。

【问题讨论】:

    标签: regex string python-3.5


    【解决方案1】:

    解决方案

    此正则表达式匹配问题中的所有地址:

    (?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b)    
    

    您需要添加所有州及其缩写,以及更匹配的邮政编码,您可以通过 google 找到。此外,这仅适用于美国地址。

    这是每个给定字符串的输出:

    >>> m = re.findall(r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))", string_1)
    >>> print m
    [('788 e.7th street, st. louis, missouri 55605', ' ', 'missouri', ' 55605')]
    >>> m = re.findall(r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))", string_2)
    >>> print m
    [('824 6th avenue, chicago, il', ' ', 'il', '')]
    >>> m = re.findall(r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))", string_3)
    >>> print m
    [('90 south seventh street, suite 5400, dubuque, iowa, 55402', ' ', 'iowa', ', 55402')]
    >>>
    

    每个元组的第一个值都有正确的地址。但是,这可能不是您所需要的(请参阅下面的弱点)。

    详情

    假设:

    • 地址以空格开头的数字
    • 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
    • 地址的其余部分位于上述两部分之间。这部分不包含任何被空格包围的数字(即没有“ \d+ ”)。

    正则表达式字符串:

    r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))"
    

    r"" 将字符串设为原始字符串以避免转义特殊字符

    (?i) 使正则表达式不区分大小写

    \d+ 地址以数字开头,后跟一个空格

    (missouri|il|iowa)(, \d{5}| \d{5}|\b)) 地址以状态结尾,可选地后跟邮政编码。 \b 只是“词尾”,这使得邮政编码是可选的。

    ((?! \d+ ).)* 任何字符组,除了被空格包围的数字。有关其工作原理的说明,请参阅 this article

    弱点

    正则表达式用于匹配模式,但与它们可能所在的字符串的其余部分相比,显示的地址没有太多模式。这是我确定的模式,也是我基于以下解决方案的模式:

    • 地址以空格开头的数字
    • 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
    • 地址的其余部分位于上述两部分之间。这部分不包含任何被空格包围的数字(即没有“ \d+ ”)。

    任何违反这些假设的地址都不会被正确匹配。例如:

    • 以带字母的数字开头的地址,例如:102A 或 3B。
    • 数字介于初始数字和州之间的地址,例如包含“7 street”而不是“7th street”的地址。

    其中一些弱点可以通过对正则表达式的简单更改来修复,但有些可能更难以修复。

    【讨论】:

    • 感谢您的努力,我现在正在检查!我有更多,每个字符串的位置。我只是添加了这两个三个词来展示一个例子。如果你看到我的编辑和第一个字符串,它实际上是这样的。
    • 我检查了它,我认为你指出了我正确的方向。谢谢!如果我有更多问题,我会确保发布它们。(因为我没有 15 分,所以我不能投票:()
    • 我的荣幸。别担心;你很快就会达到 15 分。 :)
    猜你喜欢
    • 2014-03-25
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 1970-01-01
    • 2018-11-04
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    相关资源
    最近更新 更多