当前位置:  开发笔记 > 编程语言 > 正文

如何检查Python中的字符串是否为ASCII?

如何解决《如何检查Python中的字符串是否为ASCII?》经验,为你挑选了9个好方法。

我想检查一个字符串是否是ASCII格式.

我知道ord(),但是当我尝试时ord('é'),我有TypeError: ord() expected a character, but string of length 2 found.我知道它是由我构建Python的方式引起的(如ord()文档中所述).

还有其他方法可以检查吗?



1> Vincent Marc..:

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

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"


使用编码更好,因为python 3中的字符串无解码方法,请参阅[编码/解码之间有什么区别?(python 2.x)](http://stackoverflow.com/questions/447107/whats-the-difference-between-encode-decode-python-2-x/449281#449281)
@alexis:错了.Python 2上的`str`是一个字节串.使用`.decode('ascii')`来确定所有字节是否都在ascii范围内是正确的.

2> Alexander Ko..:
def is_ascii(s):
    return all(ord(c) < 128 for c in s)


毫无意义的低效率.更好的尝试s.decode('ascii')并捕获UnicodeDecodeError,正如Vincent Marchetti所建议的那样.
与try/except相比,效率低下.这里的循环在解释器中.使用try/except形式,循环位于由str.decode('ascii')调用的C编解码器实现中.我同意,try/except形式也更加pythonic.
@JohnMachin`ord(c)<128`比`c <="\ x7F"更具可读性和直观性.
这不是低效的.all()将短路并在遇到无效字节时立即返回False.
无论效率与否,pythonic方法都是try/except.
"低效率"取决于字符串的长度和ASCII数据的可能性; 对于非ASCII的短字符串,此函数可能比设置try/except块和处理异常更快.
使用`try-catch`块不是pythonic,而是滥用.
似乎人们为成为Python而不是为理智而疯狂。对我来说,这个答案比尝试要容易得多,除了因为我想在列表理解中使用它。我想过滤掉一个大型文本语料库,把每个单词都扔掉而不是ascii。您将如何使用try..except?
-1不仅循环通过Python代码而不是C代码,而且还有一个Python函数调用`ord(c)` - UGLY - 至少使用`c <="\ x7F"`.
`.decode('ascii')`也会快速失败.

3> 小智..:

Python 3方式:

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


这是检测Unicode字符串中的非ascii字符的一个很好的小技巧,在python3中几乎都是字符串.由于ascii字符只能使用1个字节进行编码,因此任何ascii字符长度在编码为字节后都将为其大小; 而其他非ascii字符将相应地编码为2个字节或3个字节,这将增加它们的大小.
这简直太浪费了.它以UTF-8编码一个字符串,创建一个完整的其他字节串.真正的Python 3方式是`try:s.encode('ascii'); 返回True``除了UnicodeEncodeError:return False`(如上所述,但编码,因为字符串是Python 3中的Unicode).当你有代理时,这个答案也会引发Python 3中的错误(例如`isascii('\ uD800')`引发错误而不是返回'False`)
对于那些不熟悉使用lambda的人(就像我初次遇到此答案时一样),`isascii`现在是一个传递字符串的函数:`isascii('somestring')`==`True`和`isascii( 'àéç')`==`False`

4> abccd..:

Python 3.7中的新功能(bpo32677)

不再对字符串进行无聊/低效的ascii检查,新的内置str/ bytes/ bytearray方法 - .isascii()将检查字符串是否为ascii.

print("is this ascii?".isascii())
# True



5> Alvin..:

最近变成这样的东西 - 供将来参考

import chardet

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

您可以使用:

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


当然,这需要[chardet](http://pypi.python.org/pypi/chardet)库.
_chardet_仅以这样的概率猜测编码:`{'confidence':0.99,'encoding':'EUC-JP'}`(在这种情况下完全错误)

6> drs..:

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

请注意,您要捕获的异常也已更改UnicodeDecodeErrorUnicodeEncodeError.


当我在寻找python3的解决方案时,我发现了这个问题并且快速阅读这个问题并没有让我怀疑这是python 2 specfic.但这个答案真的很有帮助 - upvoting!

7> Glyph..:

你的问题不正确; 你看到的错误不是你如何构建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') == 2len(u'\u00e9') == 1.如果这对您很重要,您可以使用,在组合表格和分解表格之间进行转换unicodedata.normalize.

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


@Ben Blank:U + 0065和U + 0301*是*代码点,它们*代表'é',它们*也可以*由U + 00E9表示.谷歌"结合尖锐的口音".
'é'确实*不一定代表单个代码点.它可以是*两个*代码点(U + 0065 + U + 0301).
每个抽象字符*始终由单个代码点表示.但是,代码点可以编码为多个字节,具体取决于编码方案.即,'é'是UTF-8和UTF-16中的两个字节,以及UTF-32中的四个字节,但在每种情况下它仍然是单个代码点 - U + 00E9.

8> miya..:

这样做怎么样?

import string

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


如果您的字符串包含非字母的ASCII字符,则会失败.对于代码示例,包括换行符,空格,点,逗号,下划线和括号.

9> Max P Magee..:

我在尝试确定如何使用/编码/解码其编码我不确定的字符串(以及如何转义/转换该字符串中的特殊字符)时发现了这个问题.

我的第一步应该是检查字符串的类型 - 我没有意识到我可以从类型获得关于其格式的良好数据. 这个答案非常有帮助,并找到了我的问题的真正根源.

如果你变得粗鲁和持久

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

特别是当你在ENCODING时,确保你没有尝试unicode()一个已经是unicode的字符串 - 由于一些可怕的原因,你得到ascii编解码器错误.(另请参阅Python Kitchen配方和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')
'àéç'

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有