我有一些代码从一个com-port中提取数据,我想在打印之前确保我得到的是一个可打印的字符串(即ASCII,可能是UTF-8).这样做有功能吗?我看了上半打的地方,没有任何看起来像我想要的东西.(字符串有可打印但我没有看到任何东西(在那里,或在字符串方法中)来检查一个字符串中的每个字符是否在另一个字符串中.
注意:控制字符不能用于我的目的.
编辑:我正在寻找单一功能,而不是自己动手解决方案:
我最终得到的是:
all(ord(c) < 127 and c in string.printable for c in input_str)
Run Code Online (Sandbox Code Playgroud)
Dav*_*ebb 47
正如您所说的那样,string模块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
Run Code Online (Sandbox Code Playgroud)
您可以将两个字符串转换为集合 - 因此集合将包含字符串中的每个字符一次 - 并检查字符串创建的集合是否是可打印字符的子集:
>>> 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
Run Code Online (Sandbox Code Playgroud)
因此,总而言之,您可能希望这样做:
import string
printset = set(string.printable)
isprintable = set(yourstring).issubset(printset)
Run Code Online (Sandbox Code Playgroud)
try/ except似乎是最好的方式:
def isprintable(s, codec='utf8'):
try: s.decode(codec)
except UnicodeDecodeError: return False
else: return True
Run Code Online (Sandbox Code Playgroud)
我不会依赖string.printable,可能认为"不可打印"的控制字符通常可以"打印"以用于终端控制目的(例如,在"着色"ANSI转义序列中,如果您的终端符合ANSI标准).但是,这当然取决于你想要检查这个的确切目的! - )
在Python 3中,字符串有一个isprintable()方法:
>>> 'a, '.isprintable()
True
Run Code Online (Sandbox Code Playgroud)
对于 Python 2.7,请参阅David Webb 的回答。
>>> # Printable
>>> s = 'test'
>>> len(s)+2 == len(repr(s))
True
>>> # Unprintable
>>> s = 'test\x00'
>>> len(s)+2 == len(repr(s))
False
Run Code Online (Sandbox Code Playgroud)
这个 Python 3 字符串包含各种特殊字符:
s = 'abcd\x65\x66 äüöë\xf1 \u00a0\u00a1\u00a2 ?? \a\b\r\t\n\v\\ \231\x9a \u2640\u2642\uffff'
Run Code Online (Sandbox Code Playgroud)
如果您尝试在控制台中显示它(或使用repr),它可以很好地从该字符串中转义所有不可打印的字符:
>>> s
'abcdef äüöëñ \xa0¡¢ ?? \x07\x08\r\t\n\x0b\\ \x99\x9a ??\uffff'
Run Code Online (Sandbox Code Playgroud)
它足够聪明,可以将水平标签 ( \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)
Run Code Online (Sandbox Code Playgroud)
可能会有一些边界字符,例如不间断的空格 ( \xa0) 在此处被视为不可打印。也许它不应该是,但是那些特殊的可以被硬编码。
聚苯乙烯
您可以这样做以仅从字符串中提取可打印的字符:
>>> ''.join(ch for ch in s if is_printable(ch))
'abcdef äüöëñ ¡¢ ?? \r\t\n\\ ??'
Run Code Online (Sandbox Code Playgroud)