繁体   English   中英

如何检查字符串是 unicode 还是 ascii?

[英]How do I check if a string is unicode or ascii?

我必须在 Python 中做什么才能确定字符串具有哪种编码?

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

在 Python 2 中,字符串可能是str类型或unicode类型。 您可以通过以下方式判断使用代码:

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 字符串还是一个字节字符串

您可以使用typeisinstance

在 Python 2 中:

>>> type(u'abc')  # Python 2 unicode string literal
<type 'unicode'>
>>> type('abc')   # Python 2 byte string literal
<type 'str'>

在 Python 2 中, str只是一个字节序列。 Python 不知道它的编码是什么。 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'>

在 Python 3 中, str就像 Python 2 的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)

在 python 3.x 中,所有字符串都是 Unicode 字符序列。 并对 str 进行 isinstance 检查(默认情况下意味着 unicode 字符串)就足够了。

isinstance(x, str)

关于 python 2.x,大多数人似乎都在使用具有两个检查的 if 语句。 一种用于 str ,一种用于 unicode。

如果你想用一个语句检查你是否有一个“类似字符串”的对象,你可以执行以下操作:

isinstance(x, basestring)

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

如果 ASCII、UTF-8 和其他字节字符串是“文本”...

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

它是文本的抽象形式

阅读 McMillan在 Python 中Unicode,完全揭开PyCon 2008 的神秘面纱,它比 Stack Overflow 上的大多数相关答案更好地解释了事情。

如果你的代码需要与双方的Python 2和Python 3兼容,你不能直接使用的东西像isinstance(s,bytes)isinstance(s,unicode)无/包裹它们可尝试不同的或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)

这些都是非pythonic的,大多数时候可能有更好的方法。

使用:

import six
if isinstance(obj, six.text_type)

在六个库中,它表示为:

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

请注意,在 Python 3 上,说以下任何一项都不公平:

  • str是任何 x 的 UTFx(例如 UTF8)

  • str是 Unicode

  • str是 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 版本无关,无需版本测试或导入 6。 请评论对以下示例代码的改进,以帮助其他人。

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

您可以使用Universal Encoding Detector ,但请注意,它只会为您提供最佳猜测,而不是实际编码,因为例如不可能知道字符串“abc”的编码。 您将需要在别处获取编码信息,例如 HTTP 协议为此使用 Content-Type 标头。

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

import six if isinstance(obj, six.text_type)

一种简单的方法是检查unicode是否是内置函数。 如果是这样,那么您在 Python 2 中并且您的字符串将是一个字符串。 为了确保一切都在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])

为我工作,我希望为需要的人工作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM