使用Python从字符串中剥离所有非字母数字字符的最佳方法是什么?
在这个问题的PHP变体中提出的解决方案可能会进行一些小的调整,但对我来说似乎不太“python化”。
声明一下,我不只是想去掉句号和逗号(以及其他标点符号),还想去掉引号、括号等。
使用Python从字符串中剥离所有非字母数字字符的最佳方法是什么?
在这个问题的PHP变体中提出的解决方案可能会进行一些小的调整,但对我来说似乎不太“python化”。
声明一下,我不只是想去掉句号和逗号(以及其他标点符号),还想去掉引号、括号等。
当前回答
for char in my_string:
if not char.isalnum():
my_string = my_string.replace(char,"")
其他回答
Python 3
使用与@John Machin的答案相同的方法,但针对Python 3进行了更新:
更大的字符集 对翻译工作方式的轻微改变。
现在假定Python代码是用UTF-8编码的 (来源:PEP 3120)
这意味着包含你想要删除的所有字符的字符串会变得更大:
del_chars = ''.join(c for c in map(chr, range(1114111)) if not c.isalnum())
翻译方法现在需要使用一个翻译表,我们可以用maketrans()创建:
del_map = str.maketrans('', '', del_chars)
现在,像以前一样,任何你想要“捏碎”的字符串:
scrunched = s.translate(del_map)
使用来自@Joe Machin的最后一个计时例子,我们可以看到它仍然比re强一个数量级:
> python -mtimeit -s"d=''.join(c for c in map(chr,range(1114111)) if not c.isalnum());m=str.maketrans('','',d);s='foo-'*25" "s.translate(m)"
1000000 loops, best of 5: 255 nsec per loop
> python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
50000 loops, best of 5: 4.8 usec per loop
使用str.translate()方法。
假设你会经常这样做:
一次,创建一个包含所有你想删除的字符的字符串: Delchars = "。Join (c for c in map(chr, range(256)) if not c.isalnum()) 当你想要挤压字符串时: scrunched = s.translate(无,delchars)
安装成本可能比re.compile更有利;边际成本更低:
C:\junk>\python26\python -mtimeit -s"import string;d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s=string.printable" "s.translate(None,d)"
100000 loops, best of 3: 2.04 usec per loop
C:\junk>\python26\python -mtimeit -s"import re,string;s=string.printable;r=re.compile(r'[\W_]+')" "r.sub('',s)"
100000 loops, best of 3: 7.34 usec per loop
注意:使用字符串。可打印作为基准数据给模式'[\W_]+'一个不公平的优势;所有的非字母数字字符都在一堆…在典型的数据中,会有不止一个替换:
C:\junk>\python26\python -c "import string; s = string.printable; print len(s),repr(s)"
100 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c'
如果你给re.sub更多的工作,会发生什么:
C:\junk>\python26\python -mtimeit -s"d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s='foo-'*25" "s.translate(None,d)"
1000000 loops, best of 3: 1.97 usec per loop
C:\junk>\python26\python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
10000 loops, best of 3: 26.4 usec per loop
我只是出于好奇计算了一些函数的时间。在这些测试中,我从字符串string中删除非字母数字字符。Printable(内置字符串模块的一部分)。使用编译的'[\W_]+'和模式。Sub (", str)被发现是最快的。
$ python -m timeit -s \
"import string" \
"''.join(ch for ch in string.printable if ch.isalnum())"
10000 loops, best of 3: 57.6 usec per loop
$ python -m timeit -s \
"import string" \
"filter(str.isalnum, string.printable)"
10000 loops, best of 3: 37.9 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]', '', string.printable)"
10000 loops, best of 3: 27.5 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]+', '', string.printable)"
100000 loops, best of 3: 15 usec per loop
$ python -m timeit -s \
"import re, string; pattern = re.compile('[\W_]+')" \
"pattern.sub('', string.printable)"
100000 loops, best of 3: 11.2 usec per loop
你可以试试:
print ''.join(ch for ch in some_string if ch.isalnum())
>>> import re
>>> string = "Kl13@£$%[};'\""
>>> pattern = re.compile('\W')
>>> string = re.sub(pattern, '', string)
>>> print string
Kl13