如何检查Python中的string是否是ASCII码?

我想检查一个string是否是ASCII码。

我知道ord() ,但是当我尝试ord('é') ,我有TypeError: ord() expected a character, but string of length 2 found 。 我明白这是由我build立Python的方式(正如ord()的文档中所解释的 )引起的。

有另一种方法检查?

 def is_ascii(s): return all(ord(c) < 128 for c in s) 

我想你不是在问正确的问题 –

python中的string没有与“ascii”,utf-8或任何其他编码对应的属性。 你的string的来源(不pipe你是从文件中读取,还是从键盘input等等)都可能用ASCII编码了一个unicodestring来产生你的string,但这就是你需要去做答案的地方。

也许你可以问的问题是:“这个string是在ASCII码中编码unicodestring的结果吗? – 这可以通过尝试来回答:

 try: mystring.decode('ascii') except UnicodeDecodeError: print "it was not a ascii-encoded unicode string" else: print "It may have been an ascii-encoded unicode string" 

Python 3的方式:

 isascii = lambda s: len(s) == len(s.encode()) 

最近进入这样的事情 – 供将来参考

 import chardet encoding = chardet.detect(string) if encoding['encoding'] == 'ascii': print 'string is in ascii' 

你可以使用它:

 string_ascii = string.decode(encoding['encoding']).encode('ascii') 

你的问题是不正确的; 你看到的错误不是你如何构buildpython的结果,而是字节串和unicodestring之间的混淆。

字节string(例如python语法中的“foo”或“bar”)是八位字节的序列; 数字从0-255。 Unicodestring(例如u“foo”或u'bar“)是unicode代码点的序列; 数字从0-1112064。 但是你似乎对字符é感兴趣,字符(在你的terminal)是一个多字节的序列,代表一个字符。

而不是ord(u'é') ,试试这个:

 >>> [ord(x) for x in u'é'] 

这告诉你代码点“é”代表的序列。 它可能会给你[233],也可能给你[101,770]。

chr()代替chr()来反转这个:

 >>> unichr(233) u'\xe9' 

这个字符实际上可以表示为单个或多个unicode“代码点”,它们本身代表字形或字符。 它可以是“具有尖锐口音(即,代码点233)”或“e”(代码点101),随后是“对前一个字符的尖锐口音”(代码点770)。 因此,这个完全相同的字符可以表示为Python数据结构u'e\u0301'u'\u00e9'

大多数情况下,你不必关心这个问题,但是如果你迭代一个unicodestring,就会成为一个问题,因为迭代是通过代码点来工作的,而不是可分解的字符。 换句话说, len(u'e\u0301') == 2len(u'\u00e9') == 1 。 如果这对你很重要,你可以使用unicodedata.normalize在合成和分解的表单之间进行转换。

通过指出每个特定术语是如何引用文本表示的不同部分,这比许多程序员意识到的要复杂得多,Unicode的术语表可以作为理解其中一些问题的有用指南。

这样做怎么样?

 import string def isAscii(s): for c in s: if c not in string.ascii_letters: return False return True 

我试图确定如何使用/编码/解码一个string,其编码我不确定(以及如何转义/转换该string中的特殊字符),我发现这个问题。

我的第一步应该是检查string的types – 我没有意识到我可以从types(s)获得有关其格式的好的数据。 这个答案是非常有帮助的,并得到了我的问题的真正根源。

如果你变得粗鲁和持久

UnicodeDecodeError:'ascii'编解码器无法解码位置263中的字节0xc3:序号不在范围内(128)

特别是当你编码时,确保你没有试图unicode()一个string已经是unicode – 由于一些可怕的原因,你得到ascii编解码器错误。 (另请参阅Python的厨房食谱 ,以及Python文档教程,以更好地理解这可能是多么可怕。)

最终我确定了我想要做的是:

 escaped_string = unicode(original_string.encode('ascii','xmlcharrefreplace')) 

在debugging中也有帮助的是把我的文件中的默认编码设置为utf-8(把它放在你的python文件的开头):

 # -*- coding: utf-8 -*- 

这允许你testing特殊字符('àéç'),而不必使用unicode转义(u'\ xe0 \ xe9 \ xe7')。

 >>> specials='àéç' >>> specials.decode('latin-1').encode('ascii','xmlcharrefreplace') '&#224;&#233;&#231;' 

Vincent Marchetti有正确的想法,但str.decode在Python 3中已被弃用。在Python 3中,您可以使用str.encode进行相同的testing:

 try: mystring.encode('ascii') except UnicodeEncodeError: pass # string is not ascii else: pass # string is ascii 

请注意,您要捕获的exception也已从UnicodeDecodeError更改为UnicodeEncodeError

为了从Python 2.6(和Python 3.x)中改进Alexander的解决scheme,可以使用helper模块curses.ascii并使用curses.ascii.isascii()函数或其他各种方法: https ://docs.python.org/2.6/ 库/ curses.ascii.html

 from curses import ascii def isascii(s): return all(ascii.isascii(c) for c in s) 

您可以使用接受Posix标准[[:ASCII:]]定义的正则expression式库。

Python中的sting( str type)是一系列字节。 没有办法通过查看string来判断这一系列字节是否代表asciistring,如ISO-8859-1这样的8位字符集中的string,还是使用UTF-8或UTF-16编码的string,或者其他什么。

但是,如果您知道使用的编码,那么您可以将str decode为unicodestring,然后使用正则expression式(或循环)来检查它是否包含您所关注的范围之外的字符。

为了防止你的代码崩溃,你可能想使用try-except来捕获TypeErrors

 >>> ord("¶") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ord() expected a character, but string of length 2 found 

例如

 def is_ascii(s): try: return all(ord(c) < 128 for c in s) except TypeError: return False 
 import re def is_ascii(s): return bool(re.match(r'[\x00-\x7F]+$', s)) 

要将一个空string包含为ASCII,请将+更改为*

就像@ RogerDahl的答案一样,但是通过否定字符类别并使用search而不是find_allmatch来短路是更有效的。

 >>> import re >>> re.search('[^\x00-\x7F]', 'Did you catch that \x00?') is not None False >>> re.search('[^\x00-\x7F]', 'Did you catch that \xFF?') is not None True 

我想像一个正则expression式是非常优化的。

我使用以下来确定string是ASCII还是Unicode:

 >> print 'test string'.__class__.__name__ str >>> print u'test string'.__class__.__name__ unicode >>> 

然后使用一个条件块来定义函数:

 def is_ascii(input): if input.__class__.__name__ == "str": return True return False