使用RE-Python从字符串中提取不同格式的街道地址

时间:2018-03-02 00:34:11

标签: regex string python-3.5

我有不同格式的街道地址字符串。我尝试了这个旧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?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

<强>解决方案

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

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

您需要添加所有状态及其缩写,以及更好地匹配邮政编码,如果您谷歌搜索,您可以找到它。此外,这仅适用于美国地址。

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

>>> 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位邮政编码
  • 地址的其余部分介于上述两部分之间。这部分不包含任何由空格包围的数字(即没有&#34; \ d +&#34;)。

正则表达式字符串:

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

r""使字符串成为原始字符串,以避免转义特殊字符

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

\d+地址以数字后跟空格

开头

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

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

<强>弱点

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

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

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

  • 地址以带字母的数字开头,例如:102A或3B。
  • 在初始号码和州之间加上数字的地址,例如包含&#39; 7街&#39;而不是&#39;第7街。&#39;

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