我正在使用Python 2.7读取ASCII数据流,其中包括带小数位的非负数,还包括包含非打印,字母和标点符号的“垃圾字符”。我可以这样剥离非printables:
rawdata2 = filter(lambda x: x in string.printable, rawdata)
但是留下了这样的字符串:
Ri-G2015,2,20.23,9.13,273.1- ZW; w; K - ; - A; B`R
删除除数字和小数点(。)之外的所有内容有什么好方法,所以我留下了这个:
2015,2,20.23,9.13,273.1
答案 0 :(得分:3)
string.printable
只是一个字符串。您可以在其位置使用自己的字符串,例如:
rawdata2 = filter(lambda x: x in ',.0123456789', rawdata)
请注意,我添加了一个逗号,因为您的预期输出还包含逗号。
答案 1 :(得分:3)
更快的方法是使用正则表达式:
import re
rawdata2 = re.sub('[^0-9,.]', '', rawdata)
这只删除集合0-9 , .
以外的任何字符(用空字符串替换它们)。这是100次重复输入字符串的过滤器方法的两倍,并且更加简洁。
最快的方法(如果您处理大量文本)是使用string.translate
:
deltable = "".join(chr(c) for c in xrange(256) if chr(c) not in "0123456789,.")
rawdata2 = string.translate(rawdata, None, deltable)
这比原始过滤器方法快100倍。
答案 2 :(得分:1)
keepchars = string.digits + ",." #the characters you want to keep
rawdata2 = filter(lambda x: x in keepchars, rawdata)
由于您似乎想要将字符列入白名单,因此我不得不这样做。如果您决定将黑名单列入黑名单,string.translate()可能是个好看的地方。
答案 3 :(得分:0)
我喜欢正则表达式。它很优雅,因为我不知道... ...
In [45]: "".join([i for i in mystring if i=="." or i.isdigit() or i==','])
Out[45]: '2015,2,20.23,9.13,273.1'
答案 4 :(得分:0)
谢谢大家。我的程序不需要很快,因为它每隔几分钟只处理一行,但我很高兴了解不同方法的效率。我最终使用了以下两行:
include = set('0' '1' '2' '3' '4' '5' '6' '7' '8' '9' '.' ',')
然后
cleandata1 = ''.join(ch for ch in rawdata if ch in include)
后来我插入第三行来保存垃圾字符以供检查:
garbage = ''.join(ch for ch in rawdata if ch not in include)