【问题标题】:FInd a US street address in text (preferably using Python regex)查找文本中的美国街道地址(最好使用 Python 正则表达式)
【发布时间】:2013-08-21 21:33:01
【问题描述】:

免责声明:我非常仔细地阅读了这个帖子: Street Address search in a string - Python or Ruby 和许多其他资源。

到目前为止,没有什么对我有用。

在一些更详细的信息中,我正在寻找的是:

规则很宽松,我绝对不是要求一个涵盖所有情况的完美代码;只是一些简单的基本假设,假设地址应采用以下格式:

a) 街道号码(1...N 位);

b) 街道名称:一个或多个单词大写;

b-2) (可选)如果可以以缩写为前缀最好。 “S.”、“N.”、“E.”、“W.”

c)(可选)单元/公寓/等可以是任意数量的任意字符(包括空)

d) 街道“类型”:(“st.”、“ave.”、“way”)之一;

e) 城市名称:1 个或多个大写单词;

f)(可选)州缩写(2 个字母)

g)(可选)zip,任意 5 位数字。

以上都不需要是有效的东西(例如现有城市或邮编)。

到目前为止,我正在尝试这样的表达方式:

pat = re.compile(r'\d{1,4}( \w+){1,5}, (.*), ( \w+){1,5}, (AZ|CA|CO| NH), [0-9]{5}(-[0-9]{4})?', re.IGNORECASE)

>>> pat.search("123 East Virginia avenue, unit 123, San Ramondo, CA, 94444")

不工作,对我来说很难理解为什么。具体来说:我如何在我的模式中将一组任何单词与应该遵循的特定单词中的一个分开,例如状态缩写。还是街道“类型(”st., ave.)?

无论如何:这是我希望得到的示例: 给定 def ex_addr(文本): # re 有魔法吗 # 返回第一个地址(所有地址?)如果没有找到,则返回 None

for t in [
'The meeting will be held at 22 West Westin st., South Carolina, 12345 on Nov.-18',
'The meeting will be held at 22 West Westin street, SC, 12345 on Nov.-18',

'Hi there,\n How about meeting tomorr. @10am-sh in Chadds @ 123 S. Vancouver ave. in Ottawa? \nThanks!!!',
'Hi there,\n How about meeting tomorr. @10am-sh in Chadds @ 123 S. Vancouver avenue in Ottawa? \nThanks!!!',

'This was written in 1999 in Montreal',

"Cool cafe at 420 Funny Lane, Cupertino CA is way too cool",

"We're at a party at 12321 Mammoth Lane, Lexington MA 77777; Come have a beer!"
] print ex_addr(t)

我想得到:

'22 West Westin st., South Carolina, 12345'
'22 West Westin street, SC, 12345'
'123 S. Vancouver ave. in Ottawa'
'123 S. Vancouver avenue in Ottawa'
None # for 'This was written in 1999 in Montreal',
"420 Funny Lane, Cupertino CA",
"12321 Mammoth Lane, Lexington MA 77777"

你能帮忙吗?

【问题讨论】:

  • 看看 PLY 是否有类似的东西......我怀疑正则表达式是否足够好
  • 谢谢 Joran,我需要考虑 PLY。似乎为 nltk.ne_chunk 创建规则的曲线更陡峭,但谁知道:-)。无论如何谢谢!顺便说一句:为什么正则表达式不够好?我不需要超过 90% 的召回率.....

标签: python regex postal-code


【解决方案1】:

我刚刚在 GitHub 中遇到了这个问题,因为我遇到了类似的问题。似乎比您当前的解决方案更有效且更强大。

https://github.com/madisonmay/CommonRegex

查看代码,街道地址的正则表达式适用于更多场景。 '\d{1,4} [\w\s]{1,20}(?:street|st|avenue|ave|road|rd|highway|hwy|square|sq|trail|trl|drive|dr| court|ct|parkway|pkwy|circle|cir|boulevard|blvd)\W?(?=\s|$)'

【讨论】:

    【解决方案2】:
    \d{1,4}( \w+){1,5}, (.*), ( \w+){1,5}, (AZ|CA|CO|NH), [0-9]{5}(-[0-9]{4})?
    

    在这个正则表达式中,你有一个太多的空格(在( \w+){1,5} 之前,它已经以一个开头)。删除它,它与您的示例匹配。

    我不认为你可以假设“单元 123”或类似的会在那里,或者可能有几个(例如“建筑 A,apt 3”)。请注意,在您的初始正则表达式中,. 可能与 , 匹配,这可能导致非常长(且不需要的)匹配。 您可能应该接受几个这样的组,但数量有限制(例如,将 , (.*) 替换为 (, [^,]{1,20}){0,5}

    在任何情况下,您都可能永远无法 100% 准确地接受人们可能向他们抛出的任何变化。做很多测试!祝你好运。

    【讨论】:

    • 谢谢@remram!我只是在学习正则表达式....:-)。这是我现在的样子:任何cmets? - >>> pat = re.compile(r'\d{1,7}( \w+){1,6} (st|street|ave|avenue|ln|lane), (apt|unit|apartment)[\., ]+.*[\. ,]+(AZ|CA|CO|NH)[\. ,]\d{5}')
    • 我不确定[\., ]+ 部分的用途,请注意.* 部分可能会占用大量文本。
    猜你喜欢
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多