用Python压缩字符
我该如何用Python来实现这个功能呢:
假设我有一个这样的字符串:
A..a.b.c
我想把它变成这样:
A.a.b.c
但是我事先不知道里面有多少个点?
这就像Linux中的tr -s功能。
4 个回答
5
正则表达式替换功能很擅长找到一些特定的模式(比如重复的点),然后把这些模式替换成其他东西(比如用一个点替代多个点):
>>> import re
>>> re.sub(r'\.+', '.', 'A..a.b.c')
'A.a.b.c'
7
如果你想要一个通用的格式,把任何重复的字符序列替换成只保留一个这样的字符:
>>> import re
>>> s='aaa,,bb,c'
>>> re.sub(r'(.)(\1+)', r'\1', s)
'a,b,c'
如果你只想限制某些特定的字符:
>>> re.sub(r'([\w])(\1+)', r'\1', s)
'a,,b,c'
>>> re.sub(r'([,])(\1+)', r'\1', s)
'aaa,bb,c'
还有你的例子:
>>> s='A..a.b.c'
>>> re.sub(r'([.])(\1+)', r'\1', s)
'A.a.b.c'
4
你想把连续出现的两个或更多的点替换成一个点。可以这样做:
>>> import re
>>> re.sub(r'\.\.+', '.', 'A..a.b.c')
'A.a.b.c'
你不想也不需要把连续出现的一个或多个点替换成一个点。
>>> re.sub(r'\.+', '.', 'A..a.b.c')
'A.a.b.c'
这样做虽然也能得到相同的结果,但会多余地替换掉单个的点(在你的例子中有3个),因此速度会慢很多。
时间记录:
python -mtimeit -s"import re;subber=re.compile(r'\.+').sub;s=1000*'a.'" "subber('.',s)"
1000 loops, best of 3: 212 usec per loop
python -mtimeit -s"import re;subber=re.compile(r'\.\.+').sub;s=1000*'a.'" "subber('.',s)"
10000 loops, best of 3: 23.2 usec per loop