使用 RE 从字符串中提取不同格式的街道地址 - Python
Extract different formats street address from a string using RE - Python
我有不同格式的街道地址字符串。我试过这个旧的 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
?任何帮助将不胜感激。
解决方案
此正则表达式匹配问题中的所有地址:
(?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')]
>>>
每个元组的第一个值都有正确的地址。但是,这可能不是您所需要的(请参阅下面的弱点)。
详情
假设:
- 地址以 space
后缀的数字开头
- 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
- 地址的其余部分在上面两部分之间。这部分不包含任何被 spaces 包围的数字(即没有“\d+”)。
正则表达式字符串:
r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))"
r""
使字符串成为原始字符串以避免转义特殊字符
(?i)
使正则表达式不区分大小写
\d+
地址以数字开头,后跟 space
(missouri|il|iowa)(, \d{5}| \d{5}|\b))
地址以州结尾,可选后跟邮政编码。 \b
就是 'end of word',这使得邮政编码成为可选的。
((?! \d+ ).)*
除了被 space 包围的数字之外的任何字符组。有关其工作原理的说明,请参阅 this article。
弱点
正则表达式用于匹配模式,但与它们可能所在的字符串的其余部分相比,所显示的地址没有太多模式。这是我确定的模式,我基于解决方案在:
- 地址以 space
后缀的数字开头
- 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
- 地址的其余部分在上面两部分之间。这部分不包含任何被 spaces 包围的数字(即没有“\d+”)。
任何违反这些假设的地址都不会被正确匹配。例如:
- 以字母数字开头的地址,例如:102A 或 3B。
- 数字介于初始数字和州之间的地址,例如包含“7 街”而不是“7 街”的地址。
其中一些弱点可以通过对正则表达式进行简单的更改来修复,但有些可能更难修复。
我有不同格式的街道地址字符串。我试过这个旧的 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
?任何帮助将不胜感激。
解决方案
此正则表达式匹配问题中的所有地址:
(?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')]
>>>
每个元组的第一个值都有正确的地址。但是,这可能不是您所需要的(请参阅下面的弱点)。
详情
假设:
- 地址以 space 后缀的数字开头
- 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
- 地址的其余部分在上面两部分之间。这部分不包含任何被 spaces 包围的数字(即没有“\d+”)。
正则表达式字符串:
r"((?i)\d+ ((?! \d+ ).)*(missouri|il|iowa)(, \d{5}| \d{5}|\b))"
r""
使字符串成为原始字符串以避免转义特殊字符
(?i)
使正则表达式不区分大小写
\d+
地址以数字开头,后跟 space
(missouri|il|iowa)(, \d{5}| \d{5}|\b))
地址以州结尾,可选后跟邮政编码。 \b
就是 'end of word',这使得邮政编码成为可选的。
((?! \d+ ).)*
除了被 space 包围的数字之外的任何字符组。有关其工作原理的说明,请参阅 this article。
弱点
正则表达式用于匹配模式,但与它们可能所在的字符串的其余部分相比,所显示的地址没有太多模式。这是我确定的模式,我基于解决方案在:
- 地址以 space 后缀的数字开头
- 地址以州或其缩写结尾,可以选择后跟 5 位邮政编码
- 地址的其余部分在上面两部分之间。这部分不包含任何被 spaces 包围的数字(即没有“\d+”)。
任何违反这些假设的地址都不会被正确匹配。例如:
- 以字母数字开头的地址,例如:102A 或 3B。
- 数字介于初始数字和州之间的地址,例如包含“7 街”而不是“7 街”的地址。
其中一些弱点可以通过对正则表达式进行简单的更改来修复,但有些可能更难修复。