我有一些从com-port中提取数据的代码,我想确保在打印之前我得到的是一个可打印的字符串(即ASCII,可能是UTF-8)。这样做有功能吗?我看了上半打的地方,没有任何看起来像我想要的东西。 (string has printable但我没有看到任何内容(在the string methods中),以检查一个字符串中的每个字符是否都在另一个字符串中。
注意:控制字符不可打印用于我的目的。
编辑:我正在/正在寻找一个单一的功能,而不是一个自己动手的解决方案:
我最终得到的是:
all(ord(c) < 127 and c in string.printable for c in input_str)
答案 0 :(得分:45)
正如您所说string
module has printable
所以只是检查字符串中的所有字符是否都在printable
中:
>>> hello = 'Hello World!'
>>> bell = chr(7)
>>> import string
>>> all(c in string.printable for c in hello)
True
>>> all(c in string.printable for c in bell)
False
您可以将两个字符串转换为集合 - 因此该集合将包含字符串中的每个字符一次 - 并检查字符串is a subset of创建的集合是否为可打印字符:
>>> printset = set(string.printable)
>>> helloset = set(hello)
>>> bellset = set(bell)
>>> helloset
set(['!', ' ', 'e', 'd', 'H', 'l', 'o', 'r', 'W'])
>>> helloset.issubset(printset)
True
>>> set(bell).issubset(printset)
False
因此,总而言之,您可能希望这样做:
import string
printset = set(string.printable)
isprintable = set(yourstring).issubset(printset)
答案 1 :(得分:5)
try
/ except
似乎是最好的方式:
def isprintable(s, codec='utf8'):
try: s.decode(codec)
except UnicodeDecodeError: return False
else: return True
我不会依赖string.printable
,它可能认为“不可打印”的控制字符通常可以“打印”以用于终端控制目的(例如,在“着色”ANSI转义序列中,如果您的终端是ANSI标准)。但是,当然,这取决于你想要检查这个的确切目的! - )
答案 2 :(得分:4)
>>> # Printable
>>> s = 'test'
>>> len(s)+2 == len(repr(s))
True
>>> # Unprintable
>>> s = 'test\x00'
>>> len(s)+2 == len(repr(s))
False
答案 3 :(得分:3)
此Python 3字符串包含各种特殊字符:
s = 'abcd\x65\x66 äüöë\xf1 \u00a0\u00a1\u00a2 漢字 \a\b\r\t\n\v\\ \231\x9a \u2640\u2642\uffff'
如果您尝试在控制台中显示它(或使用repr
),则可以很好地从该字符串中转义所有不可打印的字符:
>>> s
'abcdef äüöëñ \xa0¡¢ 漢字 \x07\x08\r\t\n\x0b\\ \x99\x9a ♀♂\uffff'
足够智能识别,例如水平标签(\t
)可打印,但垂直标签(\v
)不可打印(显示为\x0b
而不是\v
)。
其他所有不可打印字符也会在\xNN
中显示为\uNNNN
或repr
。因此,我们可以将其作为测试:
def is_printable(s):
return not any(repr(ch).startswith("'\\x") or repr(ch).startswith("'\\u") for ch in s)
可能会有一些临界字符,例如不间断的空格(\xa0
)在此处被视为不可打印。也许它不应该,但那些特殊的可能是硬编码的。
P.S。
您可以这样做,只从字符串中提取可打印的字符:
>>> ''.join(ch for ch in s if is_printable(ch))
'abcdef äüöëñ ¡¢ 漢字 \r\t\n\\ ♀♂'
答案 4 :(得分:3)
在Python 3中,字符串具有isprintable()
方法:
>>> 'a, '.isprintable()
True
对于Python 2.7,请参阅Dave Webb的答案。
答案 5 :(得分:1)
# Here is the full routine to display an arbitrary binary string
# Python 2
ctrlchar = "\n\r| "
# ------------------------------------------------------------------------
def isprint(chh):
if ord(chh) > 127:
return False
if ord(chh) < 32:
return False
if chh in ctrlchar:
return False
if chh in string.printable:
return True
return False
# ------------------------------------------------------------------------
# Return a hex dump formatted string
def hexdump(strx, llen = 16):
lenx = len(strx)
outx = ""
for aa in range(lenx/16):
outx += " "
for bb in range(16):
outx += "%02x " % ord(strx[aa * 16 + bb])
outx += " | "
for cc in range(16):
chh = strx[aa * 16 + cc]
if isprint(chh):
outx += "%c" % chh
else:
outx += "."
outx += " | \n"
# Print remainder on last line
remn = lenx % 16 ; divi = lenx / 16
if remn:
outx += " "
for dd in range(remn):
outx += "%02x " % ord(strx[divi * 16 + dd])
outx += " " * ((16 - remn) * 3)
outx += " | "
for cc in range(remn):
chh = strx[divi * 16 + cc]
if isprint(chh):
outx += "%c" % chh
else:
outx += "."
outx += " " * ((16 - remn))
outx += " | \n"
return(outx)
答案 6 :(得分:0)
category
module中的unicodedata
函数可能适合您的需求。例如,您可以使用它来检查字符串中是否有任何控制字符,同时仍允许使用非ASCII字符。
>>> import unicodedata
>>> def has_control_chars(s):
... return any(unicodedata.category(c) == 'Cc' for c in s)
>>> has_control_chars('Hello 世界')
False
>>> has_control_chars('Hello \x1f 世界')
True
答案 7 :(得分:0)
Mine是一种摆脱任何已知字符集的解决方案。可能会有帮助。
non_printable_chars = set("\n\t\r ") # Space included intensionally
is_printable = lambda string:bool(set(string) - set(non_printable_chars))
...
...
if is_printable(string):
print("""do something""")
...
答案 8 :(得分:0)
ctrlchar = "\n\r| "
# ------------------------------------------------------------------------
# This will let you control what you deem 'printable'
# Clean enough to display any binary
def isprint(chh):
if ord(chh) > 127:
return False
if ord(chh) < 32:
return False
if chh in ctrlchar:
return False
if chh in string.printable:
return True
return False
答案 9 :(得分:0)
在ASCII表中,[\ x20- \ x7e]是可打印的字符。
使用正则表达式检查字符串中是否包含除这些字符之外的其他字符。
您可以确定这是否是可打印的字符串。
>>> import re
>>> # Printable
>>> print re.search(r'[^\x20-\x7e]', 'test')
None
>>> # Unprintable
>>> re.search(r'[^\x20-\x7e]', 'test\x00') != None
True
>>> # Optional expression
>>> pattern = r'[^\t-\r\x20-\x7e]'