【问题标题】:Separate city and state in string?用字符串分隔城市和州?
【发布时间】:2011-03-25 18:03:09
【问题描述】:

一个字符串,citystate,可以这样格式化:

“康涅狄格州格林威治”
“格林威治,CT”
“格林威治CT”

如何将字符串 citystate 拆分为两个单独的字符串 city 和 state(使用 Python)?

(例如城市 == 格林威治和州 == CT)

感谢您的帮助!

【问题讨论】:

  • 这仅适用于美国地址吗?还要考虑:有多个单词的城市、标点符号的城市、华盛顿特区、非大写州、拼写州、旧/其他州缩写(例如“Conn”)。

标签: python


【解决方案1】:
import re
city, state = re.split(r' ?,? ?', location)

要解决纽约问题,请使用切片:

split_loc = re.split(r' ?,? ?', location)
city = ' '.join(split_loc[:-1]) # Everything up to last element joined by space
state = split_loc[-1]

【讨论】:

  • {1} 是多余的。第二个例子在逗号前没有空格。
  • @delnan 我做了一些修改,现在我回到第一个 :) 奥卡姆剃刀,我猜。
  • @delnan 我想到了这一点,但由于某种原因,这行得通。它不会拆分“GreenwichCT”,我怀疑这与 re.split 的实现有关
  • @StephenPaulger 你可以通过切片来纠正这个问题,请参阅我的更新。
【解决方案2】:

做一些假设:

(1)一个状态码是两个字符,你将通过查找状态码表来验证拆分结果

(2) 您的输入数据已经转换为unicode (Python 2.X) 或str (Python 3.x)

(3) 您的数据可能会发生更广泛的数据输入错误和脚本小子错误。

代码:

tests = [
    u"Foo YZ", u"Foo YZ\n", u"Foo\xa0YZ", u"Foo  YZ",
    u"Foo, YZ", u"Foo, YZ\n", u"Foo,\xa0YZ",
    u"Foo,YZ", u"Foo,YZ\n", u"Foo,,YZ",
    u"FooYZ", u"   Foo \t,\xa0   YZ \n",
    ]

import re

def machin(strg):
    strg = strg.strip()
    state = strg[-2:]
    city = u" ".join(strg[:-2].split()) # normalise whitespace
    city = city.rstrip(", ")
    return city, state

def kettler(strg):
    split_loc = re.split(r' ?,? ?', strg)
    city = ' '.join(split_loc[:-1]) # Everything up to last element joined by space
    state = split_loc[-1]
    return city, state

def bothwell(strg):
    # split on last comma
    res = strg.rsplit(',', 1)
    if len(res)==2:
        return res[0].strip(), res[1].strip()
    # otherwise split on last non-trailing whitespace
    res = strg.rsplit(None, 1)
    if len(res)==2:
        return res[0].lstrip(), res[1]
    # otherwise split failed
    # raise ValueError("Could not split {0} into city, state".format(s))
    return None, None

def paulger_v2(strg):
    return strg[:-3].strip(", "), strg[-2:]


funcs = (kettler, bothwell, paulger_v2, machin)

for func in funcs:
    print "\n===", func.__name__, "==="
    nok = 0
    for test in tests:
        city, state = func(test)
        ok = city == u"Foo" and state == u"YZ"; nok += ok
        print [ok, test, city, state]
        test = test.replace(u"Foo", u"Foo  Baa")
        city, state = func(test)
        ok = city == u"Foo Baa" and state == u"YZ"; nok += ok
        print [ok, test, city, state]
    print "\n+++ %s: %d OK +++" % (func.__name__, nok)

输出:

=== kettler ===
[True, u'Foo YZ', u'Foo', u'YZ']
[True, u'Foo  Baa YZ', u'Foo Baa', u'YZ']
[False, u'Foo YZ\n', u'Foo', u'YZ\n']
[False, u'Foo  Baa YZ\n', u'Foo Baa', u'YZ\n']
[False, u'Foo\xa0YZ', '', u'Foo\xa0YZ']
[False, u'Foo  Baa\xa0YZ', u'Foo', u'Baa\xa0YZ']
[True, u'Foo  YZ', u'Foo', u'YZ']
[True, u'Foo  Baa  YZ', u'Foo Baa', u'YZ']
[True, u'Foo, YZ', u'Foo', u'YZ']
[True, u'Foo  Baa, YZ', u'Foo Baa', u'YZ']
[False, u'Foo, YZ\n', u'Foo', u'YZ\n']
[False, u'Foo  Baa, YZ\n', u'Foo Baa', u'YZ\n']
[False, u'Foo,\xa0YZ', u'Foo', u'\xa0YZ']
[False, u'Foo  Baa,\xa0YZ', u'Foo Baa', u'\xa0YZ']
[True, u'Foo,YZ', u'Foo', u'YZ']
[True, u'Foo  Baa,YZ', u'Foo Baa', u'YZ']
[False, u'Foo,YZ\n', u'Foo', u'YZ\n']
[False, u'Foo  Baa,YZ\n', u'Foo Baa', u'YZ\n']
[False, u'Foo,,YZ', u'Foo ', u'YZ']
[False, u'Foo  Baa,,YZ', u'Foo Baa ', u'YZ']
[False, u'FooYZ', '', u'FooYZ']
[False, u'Foo  BaaYZ', u'Foo', u'BaaYZ']
[False, u'   Foo \t,\xa0   YZ \n', u'  Foo \t \xa0  YZ', u'\n']
[False, u'   Foo  Baa \t,\xa0   YZ \n', u'  Foo Baa \t \xa0  YZ', u'\n']

+++ kettler: 8 OK +++

=== bothwell ===
[True, u'Foo YZ', u'Foo', u'YZ']
[False, u'Foo  Baa YZ', u'Foo  Baa', u'YZ']
[True, u'Foo YZ\n', u'Foo', u'YZ']
[False, u'Foo  Baa YZ\n', u'Foo  Baa', u'YZ']
[True, u'Foo\xa0YZ', u'Foo', u'YZ']
[False, u'Foo  Baa\xa0YZ', u'Foo  Baa', u'YZ']
[True, u'Foo  YZ', u'Foo', u'YZ']
[False, u'Foo  Baa  YZ', u'Foo  Baa', u'YZ']
[True, u'Foo, YZ', u'Foo', u'YZ']
[False, u'Foo  Baa, YZ', u'Foo  Baa', u'YZ']
[True, u'Foo, YZ\n', u'Foo', u'YZ']
[False, u'Foo  Baa, YZ\n', u'Foo  Baa', u'YZ']
[True, u'Foo,\xa0YZ', u'Foo', u'YZ']
[False, u'Foo  Baa,\xa0YZ', u'Foo  Baa', u'YZ']
[True, u'Foo,YZ', u'Foo', u'YZ']
[False, u'Foo  Baa,YZ', u'Foo  Baa', u'YZ']
[True, u'Foo,YZ\n', u'Foo', u'YZ']
[False, u'Foo  Baa,YZ\n', u'Foo  Baa', u'YZ']
[False, u'Foo,,YZ', u'Foo,', u'YZ']
[False, u'Foo  Baa,,YZ', u'Foo  Baa,', u'YZ']
[False, u'FooYZ', None, None]
[False, u'Foo  BaaYZ', u'Foo', u'BaaYZ']
[True, u'   Foo \t,\xa0   YZ \n', u'Foo', u'YZ']
[False, u'   Foo  Baa \t,\xa0   YZ \n', u'Foo  Baa', u'YZ']

+++ bothwell: 10 OK +++

=== paulger_v2 ===
[True, u'Foo YZ', u'Foo', u'YZ']
[False, u'Foo  Baa YZ', u'Foo  Baa', u'YZ']
[False, u'Foo YZ\n', u'Foo', u'Z\n']
[False, u'Foo  Baa YZ\n', u'Foo  Baa', u'Z\n']
[True, u'Foo\xa0YZ', u'Foo', u'YZ']
[False, u'Foo  Baa\xa0YZ', u'Foo  Baa', u'YZ']
[True, u'Foo  YZ', u'Foo', u'YZ']
[False, u'Foo  Baa  YZ', u'Foo  Baa', u'YZ']
[True, u'Foo, YZ', u'Foo', u'YZ']
[False, u'Foo  Baa, YZ', u'Foo  Baa', u'YZ']
[False, u'Foo, YZ\n', u'Foo', u'Z\n']
[False, u'Foo  Baa, YZ\n', u'Foo  Baa', u'Z\n']
[True, u'Foo,\xa0YZ', u'Foo', u'YZ']
[False, u'Foo  Baa,\xa0YZ', u'Foo  Baa', u'YZ']
[True, u'Foo,YZ', u'Foo', u'YZ']
[False, u'Foo  Baa,YZ', u'Foo  Baa', u'YZ']
[False, u'Foo,YZ\n', u'Foo', u'Z\n']
[False, u'Foo  Baa,YZ\n', u'Foo  Baa', u'Z\n']
[True, u'Foo,,YZ', u'Foo', u'YZ']
[False, u'Foo  Baa,,YZ', u'Foo  Baa', u'YZ']
[False, u'FooYZ', u'Fo', u'YZ']
[False, u'Foo  BaaYZ', u'Foo  Ba', u'YZ']
[False, u'   Foo \t,\xa0   YZ \n', u'Foo \t,\xa0   Y', u' \n']
[False, u'   Foo  Baa \t,\xa0   YZ \n', u'Foo  Baa \t,\xa0   Y', u' \n']

+++ paulger_v2: 7 OK +++

=== machin ===
[True, u'Foo YZ', u'Foo', u'YZ']
[True, u'Foo  Baa YZ', u'Foo Baa', u'YZ']
[True, u'Foo YZ\n', u'Foo', u'YZ']
[True, u'Foo  Baa YZ\n', u'Foo Baa', u'YZ']
[True, u'Foo\xa0YZ', u'Foo', u'YZ']
[True, u'Foo  Baa\xa0YZ', u'Foo Baa', u'YZ']
[True, u'Foo  YZ', u'Foo', u'YZ']
[True, u'Foo  Baa  YZ', u'Foo Baa', u'YZ']
[True, u'Foo, YZ', u'Foo', u'YZ']
[True, u'Foo  Baa, YZ', u'Foo Baa', u'YZ']
[True, u'Foo, YZ\n', u'Foo', u'YZ']
[True, u'Foo  Baa, YZ\n', u'Foo Baa', u'YZ']
[True, u'Foo,\xa0YZ', u'Foo', u'YZ']
[True, u'Foo  Baa,\xa0YZ', u'Foo Baa', u'YZ']
[True, u'Foo,YZ', u'Foo', u'YZ']
[True, u'Foo  Baa,YZ', u'Foo Baa', u'YZ']
[True, u'Foo,YZ\n', u'Foo', u'YZ']
[True, u'Foo  Baa,YZ\n', u'Foo Baa', u'YZ']
[True, u'Foo,,YZ', u'Foo', u'YZ']
[True, u'Foo  Baa,,YZ', u'Foo Baa', u'YZ']
[True, u'FooYZ', u'Foo', u'YZ']
[True, u'Foo  BaaYZ', u'Foo Baa', u'YZ']
[True, u'   Foo \t,\xa0   YZ \n', u'Foo', u'YZ']
[True, u'   Foo  Baa \t,\xa0   YZ \n', u'Foo Baa', u'YZ']

+++ machin: 24 OK +++

【讨论】:

  • 感谢您投入所有工作来测试这些方法。你能告诉我你是如何自动化所有这些测试的吗?
  • @Andrew:把代码读到最后……for func in funcs:……for test in tests:。顺便问一下,你检查过考试成绩中的分数吗?你对你接受的答案仍然满意吗?
【解决方案3】:
def cityState(s):
    # split on last comma
    res = s.rsplit(',', 1)
    if len(res)==2:
        return res[0].strip(), res[1].strip()
    # otherwise split on last non-trailing whitespace
    res = s.rsplit(None, 1)
    if len(res)==2:
        return res[0].lstrip(), res[1]
    # otherwise split failed
    raise ValueError("Could not split {0} into city, state".format(s))

for city_state in ["Greenwich, CT", "Greenwich,CT", "Greenwich CT", "New York, NY"]:
    print "City '{0}' is in '{1}'".format(*cityState(city_state))

结果

City 'Greenwich' is in 'CT'
City 'Greenwich' is in 'CT'
City 'Greenwich' is in 'CT'
City 'New York' is in 'NY'

【讨论】:

    【解决方案4】:

    在您给定的示例中,state 始终是最后两个字符 citystate[-2:] 并且 city 始终是减去尾随空格和逗号的所有内容。

    我将添加一个额外的示例“纽约,纽约”。

    citystates = ["Greenwich, CT", "Greenwich,CT", "Greenwich CT", "New York, NY"]
    
    for citystate in citystates:
        city, state = citystate[:-3].strip(", "), citystate[-2:]
        print "City '%s' is in '%s' % (city, state)
    

    运行时给出:

    City 'Greenwich' is in 'CT'
    City 'Greenwich' is in 'CT'
    City 'Greenwich' is in 'CT'
    City 'New York' is in 'NY'
    

    【讨论】:

    • -1 你没有测试过这个;通过检查您的代码,您的第一个和第二个示例不能产生相同的答案。 "Greenwich, CT"[:-3] 产生 'Greenwich,'
    • 抱歉,我确实测试过了。我只是忘了放入我的解释器中包含的 strip(", ") 。现已更正。
    • 我在这个网站上发布答案不会得到报酬,所以对于简单的答案,我不倾向于编写单元测试。有时我只是在 python shell 中编写它,在这种情况下,这意味着我最终复制了我想在离开办公室之前发布的错误代码,或者我根本无法发布它。当我回到家时,你指出了错误,所以我纠正了它。如果您认为稍微不正确的答案比没有答案更糟糕,那么您有权投反对票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    相关资源
    最近更新 更多