如何检查字符串是否为unicode或ascii?

我必须在Python中做什么来找出字符串的编码?

442080 次浏览

如何判断一个对象是unicode字符串还是字节字符串

你可以使用typeisinstance

在Python 2中:

>>> type(u'abc')  # Python 2 unicode string literal
<type 'unicode'>
>>> type('abc')   # Python 2 byte string literal
<type 'str'>
在python2中,str只是一个字节序列。巨蟒不知道 它的编码是。unicode类型是存储文本的更安全的方式。 如果你想了解更多,我推荐http://farmdev.com/talks/unicode/.

在Python 3中:

>>> type('abc')   # Python 3 unicode string literal
<class 'str'>
>>> type(b'abc')  # Python 3 byte string literal
<class 'bytes'>
在python3中,str类似于python2的unicode,并且用于 存储文本。在Python 2中被称为str的东西在Python 3中被称为bytes

如何判断一个字节字符串是有效的utf-8或ascii

你可以调用decode。如果它引发UnicodeDecodeError异常,则它是无效的。

>>> u_umlaut = b'\xc3\x9c'   # UTF-8 representation of the letter 'Ü'
>>> u_umlaut.decode('utf-8')
u'\xdc'
>>> u_umlaut.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)

你可以使用通用编码检测器,但请注意,它只会给你最好的猜测,而不是实际的编码,因为不可能知道字符串"abc"的编码。您将需要在其他地方获取编码信息,例如HTTP协议使用内容类型报头。

在python3中,所有字符串都是Unicode字符的序列。有一个bytes类型保存原始字节。

在python2中,字符串的类型可以是strunicode。你可以用如下代码来区分:

def whatisthis(s):
if isinstance(s, str):
print "ordinary string"
elif isinstance(s, unicode):
print "unicode string"
else:
print "not a string"

这并不区分“Unicode或ASCII”;它只区分Python类型。Unicode字符串可以由ASCII范围内的纯字符组成,字节字符串可以包含ASCII、编码的Unicode,甚至是非文本数据。

Unicode不是一种编码——引用Kumar McMillan的话:

如果ASCII, UTF-8和其他字节字符串是“text”…

...那么Unicode就是“文本性”;

它是文本的抽象形式

读一读McMillan在PyCon 2008上的在Python中,完全去神秘化演讲,它比Stack Overflow上的大多数相关答案更好地解释了事情。

如果你的代码需要与这两个 Python 2和Python 3兼容,你不能直接使用isinstance(s,bytes)isinstance(s,unicode)这样的东西,而不将它们包装在try/except或Python版本测试中,因为bytes在Python 2中未定义,而unicode在Python 3中未定义。

有一些丑陋的变通办法。一个极其丑陋的例子是比较类型的的名字,而不是比较类型本身。这里有一个例子:

# convert bytes (python 3) or unicode (python 2) to str
if str(type(s)) == "<class 'bytes'>":
# only possible in Python 3
s = s.decode('ascii')  # or  s = str(s)[2:-1]
elif str(type(s)) == "<type 'unicode'>":
# only possible in Python 2
s = str(s)

一个稍微不那么丑陋的解决方法是检查Python版本号,例如:

if sys.version_info >= (3,0,0):
# for Python 3
if isinstance(s, bytes):
s = s.decode('ascii')  # or  s = str(s)[2:-1]
else:
# for Python 2
if isinstance(s, unicode):
s = str(s)

这两个都是非python的,大多数时候可能有更好的方法。

在python中3。x所有字符串都是Unicode字符的序列。使用isinstance检查STR(默认为unicode字符串)就足够了。

isinstance(x, str)
关于python 2.x, 大多数人似乎都在使用带有两次检查的if语句。一个用于STR,一个用于unicode

如果你想检查你是否有一个'string-like'的对象,并且只有一个语句,你可以这样做:

isinstance(x, basestring)

注意,在Python 3中,这样说并不公平:

  • __abc0是任何x的UTFx(例如。use UTF8)

  • __abc0是Unicode

  • __abc0是Unicode字符的有序集合

Python的str类型(通常)是一个Unicode码位序列,其中一些映射到字符。


即使在Python 3上,回答这个问题也不像您想象的那么简单。

测试ascii兼容字符串的一个明显的方法是尝试编码:

"Hello there!".encode("ascii")
#>>> b'Hello there!'


"Hello there... ☃!".encode("ascii")
#>>> Traceback (most recent call last):
#>>>   File "", line 4, in <module>
#>>> UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 15: ordinal not in range(128)

这个错误区分了不同的情况。

在Python 3中,甚至有一些字符串包含无效的Unicode代码点:

"Hello there!".encode("utf8")
#>>> b'Hello there!'


"\udcc3".encode("utf8")
#>>> Traceback (most recent call last):
#>>>   File "", line 19, in <module>
#>>> UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc3' in position 0: surrogates not allowed

用同样的方法来区分它们。

这可能会帮助其他人,我开始测试变量s的字符串类型,但对于我的应用程序,更有意义的是简单地返回s为utf-8。调用return_utf的进程知道它在处理什么,并可以适当地处理字符串。代码不是原始的,但我希望它是Python版本不可知的,不需要版本测试或导入六个版本。请对下面的示例代码进行改进,以帮助其他人。

def return_utf(s):
if isinstance(s, str):
return s.encode('utf-8')
if isinstance(s, (int, float, complex)):
return str(s).encode('utf-8')
try:
return s.encode('utf-8')
except TypeError:
try:
return str(s).encode('utf-8')
except AttributeError:
return s
except AttributeError:
return s
return s # assume it was already utf-8

使用:

import six
if isinstance(obj, six.text_type)

在六个库中,它被表示为:

if PY3:
string_types = str,
else:
string_types = basestring,

对于py2/py3兼容性,只需使用

< p > <代码> 进口六 如果isinstance(obj, six.text_type) < /代码> < / p >

一个简单的方法是检查unicode是否是内置函数。如果是,你在python2中,你的字符串将是一个字符串。要确保所有内容都在unicode中,可以这样做:

import builtins


i = 'cats'
if 'unicode' in dir(builtins):     # True in python 2, False in 3
i = unicode(i)

在Python-3中,我必须理解string是否像b='\x7f\x00\x00\x01'b='127.0.0.1'。我的解决方案是这样的:

def get_str(value):
str_value = str(value)
    

if str_value.isprintable():
return str_value


return '.'.join(['%d' % x for x in value])

对我有用,我希望对有需要的人有用