如何过滤字符串,仅返回列表中的字符?

24 投票
10 回答
32074 浏览
提问于 2025-04-15 11:37

想象一下有一个字符串,比如 'Agh#$%#%2341- -!zdrkfd',我只想对它进行一些操作,让它只返回小写字母(作为例子),在这个情况下,结果就是 'ghzdrkfd'。

在Python中怎么做呢?最简单的方法就是先创建一个包含字母 'a' 到 'z' 的列表,然后逐个检查我字符串中的字符,只有在这个列表里的字符才会被加到一个新的字符串中。这样做感觉有点原始。

我在想正则表达式是否合适。替换掉不需要的字符似乎有点麻烦,我更喜欢用白名单而不是黑名单。.match 函数似乎不太合适。我查过Python官网的相关页面,但没有找到合适的方法。

如果正则表达式不合适,而正确的方法是循环,那有没有简单的函数可以把字符串“拆分”成一个列表呢?还是说我又要用另一个循环了?

10 个回答

6

使用正则表达式其实很简单,特别是在这种情况下:

>>> import re
>>> s = 'ASDjifjASFJ7364'
>>> re.sub(r'[^a-z]+', '', s)
'jifj'

如果你打算多次使用这个正则表达式,最好提前编译好它:

>>> import re
>>> s = 'ASDjifjASFJ7364'
>>> r = re.compile(r'[^a-z]+')
>>> r.sub('', s)
'jifj'
18
s = 'Agh#$%#%2341- -!zdrkfd'  
print ''.join(c for c in s if c.islower())

字符串对象是可以被遍历的;所以不需要把字符串拆分成列表。你可以在列表推导式中放入任何条件,它会根据这些条件来筛选字符。

你也可以用正则表达式来实现这个功能,但这只是把循环隐藏起来了。正则表达式库仍然需要遍历字符串中的字符来进行筛选。

32

如果你想提高效率,使用 translate 函数是最快的方法。

这个函数可以快速替换字符,或者直接删除字符。

import string
delete_table  = string.maketrans(
    string.ascii_lowercase, ' ' * len(string.ascii_lowercase)
)
table = string.maketrans('', '')

"Agh#$%#%2341- -!zdrkfd".translate(table, delete_table)

在 Python 2.6 中:你不再需要第二个表格了。

import string
delete_table  = string.maketrans(
    string.ascii_lowercase, ' ' * len(string.ascii_lowercase)
)
"Agh#$%#%2341- -!zdrkfd".translate(None, delete_table)

这个方法比其他任何方法都要快。当然,你需要把删除的字符表存储起来并使用它。但即使你不存储每次都重新生成,它的速度还是会比其他推荐的方法快。

为了证明我的说法,这里有一些结果:

for i in xrange(10000):
    ''.join(c for c in s if c.islower())

real    0m0.189s
user    0m0.176s
sys 0m0.012s

在运行正则表达式解决方案时:

for i in xrange(10000):
    re.sub(r'[^a-z]', '', s)

real    0m0.172s
user    0m0.164s
sys 0m0.004s

[应请求] 如果你预先编译正则表达式:

r = re.compile(r'[^a-z]')
for i in xrange(10000):
    r.sub('', s)

real    0m0.166s
user    0m0.144s
sys 0m0.008s

运行 translate 方法相同次数所需的时间是:

real    0m0.075s
user    0m0.064s
sys 0m0.012s

撰写回答