如何过滤字符串,以便只返回列表中的字符?

22 python whitelist filter

想象一个字符串,比如'Agh#$%#%2341- - !zdrkfd',我只想对它进行一些操作,只返回小写字母(例如),在这种情况下会带来'ghzdrkfd ".

你是如何用Python做到的?显而易见的方法是创建一个字符列表,'a'到'z',然后迭代我的字符串中的字符,并逐个字符地构建一个新字符串.这似乎很原始.

我想知道正则表达式是否合适.替换不需要的字符似乎有问题,我倾向于将白名单优先于黑名单.该.match功能似乎不合适.我查看了Python网站上的相应页面,但还没有找到一个似乎合适的方法.

如果正则表达式不合适并且正确的方法是循环,是否有一个简单的函数将字符串"爆炸"到列表中?或者我只是在那里打另一个循环?

Nad*_*mli 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)
Run Code Online (Sandbox Code Playgroud)

在python 2.6中:你不再需要第二个表了

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

这种方法比任何其他方法都快.当然你需要在某处存储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
Run Code Online (Sandbox Code Playgroud)

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

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

real    0m0.172s
user    0m0.164s
sys 0m0.004s
Run Code Online (Sandbox Code Playgroud)

[根据请求]如果您预编译正则表达式:

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

real    0m0.166s
user    0m0.144s
sys 0m0.008s
Run Code Online (Sandbox Code Playgroud)

运行translate方法的次数相同:

real    0m0.075s
user    0m0.064s
sys 0m0.012s
Run Code Online (Sandbox Code Playgroud)

  • 公平地说,你应该在循环外编译正则表达式. (2认同)

Aym*_*ieh 18

s = 'Agh#$%#%2341- -!zdrkfd'  
print ''.join(c for c in s if c.islower())
Run Code Online (Sandbox Code Playgroud)

字符串对象是可迭代的; 没有必要将字符串"爆炸"到列表中.您可以在列表推导中放置您想要的任何条件,它将相应地过滤字符.

您也可以使用正则表达式来实现它,但这只会隐藏循环.正则表达式库仍然必须循环遍历字符串的字符才能过滤它们.

  • 通过将`c.islower()`更改为例如`c in"abcDEF"`,也可以修改它以使用自定义字符列表. (3认同)

Pao*_*ino 5

使用正则表达式很容易,特别是对于这种情况:

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

如果您打算多次这样做,最好先编译正则表达式:

>>> import re
>>> s = 'ASDjifjASFJ7364'
>>> r = re.compile(r'[^a-z]+')
>>> r.sub('', s)
'jifj'
Run Code Online (Sandbox Code Playgroud)


Jas*_*oon 4

s = 'ASDjifjASFJ7364'
s_lowercase = ''.join(filter(lambda c: c.islower(), s))
print s_lowercase #print 'jifj'
Run Code Online (Sandbox Code Playgroud)

  • 无需在 s 上调用 list。字符串对象是可迭代的。 (3认同)