我想检查字符串是否为ASCII。
我知道ord()
,但是当我尝试时ord('é')
,我知道了TypeError: ord() expected a character, but string of length 2 found
。我了解这是由我构建Python的方式引起的(如ord()
的文档中所述)。
还有另一种检查方法吗?
我想检查字符串是否为ASCII。
我知道ord()
,但是当我尝试时ord('é')
,我知道了TypeError: ord() expected a character, but string of length 2 found
。我了解这是由我构建Python的方式引起的(如ord()
的文档中所述)。
还有另一种检查方法吗?
Answers:
def is_ascii(s):
return all(ord(c) < 128 for c in s)
ord(c) < 128
比c <= "\x7F"
我认为您不是在问正确的问题-
python中的字符串没有与'ascii',utf-8或任何其他编码对应的属性。字符串的来源(无论您是从文件中读取字符串,还是从键盘输入等等)可能已经在ASCII中编码了一个unicode字符串以生成您的字符串,但这就是您需要答案的地方。
也许您会问的问题是:“此字符串是在ASCII中编码unicode字符串的结果吗?” -您可以尝试以下方法回答:
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"
str
在Python 2中,bytes
在Python 3中)。
str
任何ISO编码中的A 都需要先编码为Unicode。答案应该在此。
s.decode('ascii') if isinstance(s, bytes) else s.encode('ascii')
在Python 3中。OP 的输入是一个字节串'é'
(Python 2语法,当时尚未发布Python 3),因此.decode()
是正确的。
str
在Python 2上是一个字节串。.decode('ascii')
找出所有字节是否都在ascii范围内是正确的。
Python 3方式:
isascii = lambda s: len(s) == len(s.encode())
要进行检查,请传递测试字符串:
str1 = "♥O◘♦♥O◘♦"
str2 = "Python"
print(isascii(str1)) -> will return False
print(isascii(str2)) -> will return True
isascii
,现在可以传递一个字符串:isascii('somestring')
== True
和isascii('àéç')
==False
try: s.encode('ascii'); return True
except UnicodeEncodeError: return False
(就像上面一样,但是编码,因为字符串在Python 3中是Unicode)。当您有代理人时,此答案还会在Python 3中isascii('\uD800')
引发错误(例如,引发错误而不是返回错误False
)
没有更多的无聊/对字符串低效ASCII检查,新的内置str
/ bytes
/ bytearray
方法- .isascii()
将检查字符串是ASCII。
print("is this ascii?".isascii())
# True
"\x03".isascii()
也是如此。文档说这只是检查所有字符是否在代码点128(0-127)以下。如果您还想避免使用控制字符,则需要:text.isascii() and text.isprintable()
。isprintable
仅靠单独使用也是不够的,因为它将认为像¿这样的字符是(正确)可打印的,但是它不在ascii可打印的部分之内,因此,您需要同时检查这两个字符。还有一个陷阱:空格被认为是可打印的,制表符和换行符则不可。
最近遇到了类似的情况-供将来参考
import chardet
encoding = chardet.detect(string)
if encoding['encoding'] == 'ascii':
print 'string is in ascii'
您可以使用:
string_ascii = string.decode(encoding['encoding']).encode('ascii')
{'confidence': 0.99, 'encoding': 'EUC-JP'}
在这种情况下是完全错误的)
Vincent Marchetti的想法正确,但str.decode
已在Python 3中弃用。在Python 3中,您可以使用以下命令进行相同的测试str.encode
:
try:
mystring.encode('ascii')
except UnicodeEncodeError:
pass # string is not ascii
else:
pass # string is ascii
请注意,您要捕获的异常也已从更改UnicodeDecodeError
为UnicodeEncodeError
。
'é'
当时是一个字节串。
您的问题不正确;您看到的错误不是您构建python的结果,而是字节字符串和unicode字符串之间的混淆。
字节字符串(例如python语法中的“ foo”或“ bar”)是八位字节序列;0-255之间的数字。Unicode字符串(例如u“ foo”或u'bar')是unicode代码点的序列;从0-1112064开始的数字。但是您似乎对字符é感兴趣,该字符é(在您的终端中)是一个多字节序列,代表一个字符。
代替ord(u'é')
,试试这个:
>>> [ord(x) for x in u'é']
这就告诉您“é”代表的代码点顺序。它可以给您[233],也可以给您[101,770]。
除了chr()
扭转这种情况,还有unichr()
:
>>> unichr(233)
u'\xe9'
该字符实际上可以表示为单个或多个unicode“代码点”,它们本身表示字素或字符。它可以是“带有重音符号的e(即代码点233)”,也可以是“ e”(编码点101),后跟“上一个字符具有重音符号”(代码点770)。因此,这个完全相同的字符可以表示为Python数据结构u'e\u0301'
或u'\u00e9'
。
大多数情况下,您不必关心这一点,但是如果您要遍历unicode字符串,这可能会成为问题,因为迭代是通过代码点而不是通过可分解字符进行的。换句话说,len(u'e\u0301') == 2
和len(u'\u00e9') == 1
。如果您认为这很重要,可以使用来在合成和分解形式之间进行转换unicodedata.normalize
。
Unicode词汇表可以指出每个特定术语如何指代文本表示形式的不同部分,这对于理解其中的一些问题可能是有用的指南,这比许多程序员意识到的要复杂得多。
我在尝试确定如何使用/编码/解码我不确定其编码的字符串(以及如何转义/转换该字符串中的特殊字符)时发现了这个问题。
我的第一步应该是检查字符串的类型-我不知道在那里可以从类型中获取有关其格式的良好数据。 这个答案非常有帮助,并且是我问题的真正根源。
如果您变得粗鲁和执着
UnicodeDecodeError:'ascii'编解码器无法解码位置263的字节0xc3:序数不在范围内(128)
尤其是在进行编码时,请确保您不尝试对已经是unicode的字符串进行unicode()-出于某种可怕的原因,您会遇到ascii编解码器错误。(另请参阅“ Python厨房食谱 ”和“ Python文档”教程,以更好地了解它的可怕程度。)
最终,我确定我想做的是:
escaped_string = unicode(original_string.encode('ascii','xmlcharrefreplace'))
在调试中也很有帮助,是将我文件中的默认编码设置为utf-8(将其放在python文件的开头):
# -*- coding: utf-8 -*-
这样,您就可以测试特殊字符('àéç'),而不必使用它们的Unicode转义符(u'\ xe0 \ xe9 \ xe7')。
>>> specials='àéç'
>>> specials.decode('latin-1').encode('ascii','xmlcharrefreplace')
'àéç'
要从Python 2.6(和Python 3.x)中改进Alexander的解决方案,可以使用帮助器模块curses.ascii并使用curses.ascii.isascii()函数或其他各种功能:https ://docs.python.org/2.6/ library / curses.ascii.html
from curses import ascii
def isascii(s):
return all(ascii.isascii(c) for c in s)
curses.ascii
为防止代码崩溃,您可能需要使用a 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
try
包装器是完全没有意义的。如果"¶"
是Unicode字符串,则ord("¶")
可以使用;如果不是,则可以使用(Python 2),for c in s
将其分解为字节,以便ord
继续使用。
我使用以下命令确定字符串是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
is_ascii(u'i am ascii')
。即使字母和空格绝对是ASCII,这仍然会返回,False
因为我们将字符串强制为unicode
。