简单、更安全的字符串操作Python

2024-10-02 16:32:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Python做了很多业余的数据清理和清理工作,这比用Excel要快得多。但我觉得我做任何事都很辛苦。最大的痛苦是,我不知道如何安全地从列表索引或字符串索引中获取,而不会出现错误,也不知道如何在代码中一层接一层地使用不可读的try/except。你知道吗

下面是一个例子,我刚刚想出了清理城市/州组合Trulia配置文件url。有时它们不给出状态,但模式是相当标准化的。你知道吗

checkstr = 'http://www.trulia.com/profile/agent-name-agent-orlando-fl-24408364/'

state = ''
citystrs = re.findall('-agent-(.*)-\d', checkstr)[0:1]
print citystrs
for citystr in citystrs:
    if '-' in citystr:
        if len(citystr.split('-')[-1]) == 2:
            state = citystr.split('-')[-1].upper().strip()
            city = string.replace(citystr.upper(), state, '')
            city = string.replace(city, '-', ' ').title().strip()
        else:
            city = string.replace(citystr, '-', ' ').title().strip()
    else:
        city = citystr.title().strip()

print city, state

我不需要多个“答案”,但我使用切片[0:1]和for,因为每当模式不适合findall[0]时,我不希望错误停止我的代码(执行此操作约200万次)。你知道吗

我能得到一些关于pythonic(和高效的)方法的建议吗?你知道吗

编辑1:我没有寻找不合格的字符串。我希望足够安全,让它贯穿每一件事并“尽其所能”(即,更符合>;更少)

编辑2:这个例子遗漏了一个非常明显的细节:多个单词的城市有内部破折号('-')。例如agent-name-los-angeles-82348233/


Tags: 字符串代码citystringtitle错误模式replace
3条回答
  • 当您只寻找第一个匹配时,使用re.search而不是findall会更清楚。你知道吗
  • 如果可能有多个匹配项(正如使用[0:1]所建议的那样),请注意.*是贪婪的。例如,从字符串-agent-orlando-fl-24408364-agent-orlando-fl-24408364中,regex捕获orlando-fl-24408364-agent-orlando-fl。改用.*?。你知道吗
  • rpartitionstring方法在最后一次出现分隔符时进行拆分,并始终返回三个字符串,这使得处理角点情况更加容易。你知道吗

建议代码:

m = re.search('-agent-(.*?)-\d', checkstr)
if m:
    citystr = m.group(1)
    city, _, state = citystr.rpartition('-')
    if len(state) <> 2:
        city = citystr
        state = ''
    city = city.replace('-', ' ').title()
    state = state.upper()

为什么不用切片呢?你知道吗

if '-' in citystr:
    sep_index = citystr.find('-')
    city = citystr[0:sep_index].title()
    state = citystr[sep_index+1:].upper()
else:
    city = citystr.title()

使用timeit(数字=10000):

yours : 3.56353430347
mine :  1.04823075931

我会这样做:

import re

reg = re.compile(r'-agent-(?P<city>[^-]*)(?:-(?P<state>[^-]*))?-\d')    

checkstr = 'http://www.trulia.com/profile/agent-name-agent-orlando-fl-24408364/'

m = reg.search(checkstr)

city = m.group('city').title()
state = m.group('state').upper() if (m.group('state')) else ''

print city, state

如果需要多次使用该模式,可以使用re.compile一次性编译它

我没有使用.*这是非常宽容的,并生成回溯,而是使用[^-]*(所有这些都不是零次或多次破折号),在第一个破折号之前停止。你知道吗

状态和前面的破折号位于可选组:(?:-(?P<state>[^-]*))?。因此,即使字符串没有状态部分,模式也会成功。你知道吗

有了这个更改re.findall就不再需要了,您可以使用re.search返回一个结果。请注意,如果您不确定字符串格式,则始终可以添加测试以检查是否存在匹配项。你知道吗

为了使代码更具可读性,我使用命名的captures(?P<name>...)。因此,通过这种方式,您可以轻松地检索组的内容:m.group('name')。但是,如果您想稍微提高速度,可以使用数字组(但这不是很重要)。你知道吗

相关问题 更多 >