从字符串中删除小写子字符串的快速方法?

Posted

技术标签:

【中文标题】从字符串中删除小写子字符串的快速方法?【英文标题】:fast way to remove lowercase substrings from string? 【发布时间】:2013-03-04 11:21:52 【问题描述】:

在 Python 中(普通或使用 numpy)从字符串 s 中删除所有小写子字符串的有效方法是什么?

s = "FOObarFOOObBAR"
remove_lower(s) => "FOOFOOBAR"

【问题讨论】:

【参考方案1】:

Python3.x 答案:

你可以制作一个字符串翻译表。创建转换表后,您可以重复使用它:

>>> import string
>>> table = str.maketrans('', '', string.ascii_lowercase)
>>> s = 'FOObarFOOObBAR'
>>> s.translate(table)
'FOOFOOOBAR'

以这种方式使用时,第一个参数值映射到第二个参数值(如果存在)。如果不存在,则假定为恒等映射。第三个参数是要移除的值的集合。


任何关心的人的旧 python2.x 答案:

我会使用str.translate。如果您为翻译表传递None,则仅执行删除步骤。在这种情况下,我将ascii_lowercase 作为要删除的字母传递。

>>> import string
>>> s = 'FOObarFOOObBAR'
>>> s.translate(None, string.ascii_lowercase)
'FOOFOOOBAR'

我怀疑你会找到更快的方法,但如果有人有动力,总有timeit 比较不同的选择:)。

【讨论】:

字符串模块不是已经弃用了吗? @DiegoHerranz -- 似乎不是。在reference docs 上搜索“depr”并没有出现任何结果。我认为这是一个普遍的谣言,因为其中的大多数方法只是内置 str 类型的别名,因此它们将来可能会被弃用。 我认为不推荐使用的是(函数版本的)方法。例如,在 python 3.3 中,只有 ascii_lowercasepunctuation 这样的常量以及 FormatterTemplate 这样的类。没有rindexsplit 啊,大概就是这样 :-) 这仅适用于字节字符串。如果字符串 s 是 unicode,则上面的代码将失败并显示 TypeError: translate() takes exactly one argument (2 given)。由于字符串在 Python 3 中默认为 unicode,因此这在 Python 3 中不起作用。【参考方案2】:

我的第一个方法是''.join(x for x in s if not x.islower())

如果您需要速度,请使用 mgilson 答案,它会快很多。

>>> timeit.timeit("''.join(x for x in 'FOOBarBaz' if not x.islower())")
3.318969964981079

>>> timeit.timeit("'FOOBarBaz'.translate(None, string.ascii_lowercase)", "import string")
0.5369198322296143

>>> timeit.timeit("re.sub('[a-z]', '', 'FOOBarBaz')", "import re")
3.631659984588623

>>> timeit.timeit("r.sub('', 'FOOBarBaz')", "import re; r = re.compile('[a-z]')")
1.9642360210418701

>>> timeit.timeit("''.join(x for x in 'FOOBarBaz' if x not in lowercase)", "lowercase = set('abcdefghijklmnopqrstuvwxyz')")
2.9605889320373535

【讨论】:

+1 对当前的两个答案,但我更喜欢这个有两个原因。 #1 是我一直使用 genexps,所以我不必考虑语法。我永远不记得translatemaketrans 是如何工作的。 #2 是这种方法更稳健:如果需求稍有变化,则更有可能存活。 @DSM -- 我也很难记住translatemaketrans 是如何工作的,但我已经习惯了。烦人的部分是直到python3.x才没有str.maketrans,所以如果你真的想使用翻译表,你实际上需要import字符串。 如果您创建一个小写字符的本地set,看看性能如何变化可能会很有趣。然后你可以测试集合中的成员而不是查看x.islower()。当然,除非您可以预先计算该集合,否则您可能一无所获。您不想在每次迭代时都这样做。为了加快大约 30% 的速度(根据我的经验——没有实际时间),您还可以使用 list-comp 代替生成器表达式。【参考方案3】:
import re

remove_lower = lambda text: re.sub('[a-z]', '', text)

s = "FOObarFOOObBAR"
s = remove_lower(s)

print(s)

【讨论】:

以上是关于从字符串中删除小写子字符串的快速方法?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中替换不区分大小写的文字子字符串

第24讲:Python字符串大小写转换对齐子串的替换

Hive - 从字符串中删除子字符串

从字符串中删除多个子字符串 - Java

从字符串中删除子字符串

使用 sed 从字符串中删除子字符串