2

所以我以前做过这个,对于这样一个看似简单的任务,这是一个令人惊讶的丑陋代码。

目标是将任何不可打印的字符转换为. (点)。出于我的目的,“可打印”确实从string.printable(换行符、制表符等)中排除了最后几个字符。这是用于打印诸如旧的 MS-DOS 调试“十六进制转储”格式之类的东西......或任何类似的东西(额外的空白将破坏预期的转储布局)。

我知道我可以使用string.translate(),并且要使用它,我需要一个翻译表。所以我用string.maketrans()它。这是我能想到的最好的:

filter = string.maketrans(
   string.translate(string.maketrans('',''),
   string.maketrans('',''),string.printable[:-5]),
   '.'*len(string.translate(string.maketrans('',''),
   string.maketrans('',''),string.printable[:-5])))

...这是一个难以理解的混乱(尽管它确实有效)。

从那里你可以调用使用类似的东西:

for each_line in sometext:
    print string.translate(each_line, filter)

... 而且要快乐。(只要你不看引擎盖)。

现在,如果我将那个可怕的表达式分解成单独的语句,它会更具可读性:

ascii = string.maketrans('','')   # The whole ASCII character set
nonprintable = string.translate(ascii, ascii, string.printable[:-5])  # Optional delchars argument
filter = string.maketrans(nonprintable, '.' * len(nonprintable))

仅仅为了易读性而这样做是很诱人的。

但是,我一直认为必须有一种更优雅的方式来表达这一点!

4

4 回答 4

5

这是使用列表推导的另一种方法:

filter = ''.join([['.', chr(x)][chr(x) in string.printable[:-5]] for x in xrange(256)])
于 2009-11-26T00:20:08.363 回答
4

在这里最广泛地使用“ascii”,但你明白了

>>> import string
>>> ascii="".join(map(chr,range(256)))
>>> filter="".join(('.',x)[x in string.printable[:-5]] for x in ascii)
>>> ascii.translate(filter)
'................................ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.................................................................................................................................'

如果我在打高尔夫球,可能会使用这样的东西:

filter='.'*32+"".join(map(chr,range(32,127)))+'.'*129
于 2009-11-26T00:19:56.063 回答
1

对于实际的代码高尔夫,我想你会完全避免 string.maketrans

s=set(string.printable[:-5])
newstring = ''.join(x for x in oldstring if x in s else '.')

或者

newstring=re.sub('[^'+string.printable[:-5]+']','',oldstring)
于 2009-11-26T00:19:01.907 回答
1

我不觉得这个解决方案丑陋。它肯定比任何基于正则表达式的解决方案更有效。这是一个更短的解决方案。但仅适用于python2.6:

nonprintable = string.maketrans('','').translate(None, string.printable[:-5])
filter = string.maketrans(nonprintable, '.' * len(nonprintable))
于 2009-11-26T00:19:21.090 回答