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

2025-02-12 10:03:00
admin
原创
45
摘要:问题描述:我想检查一个字符串是否是 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()的文档中所述)。

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


解决方案 1:

我认为你问的问题不对——

python 中的字符串没有与 'ascii'、utf-8 或任何其他编码相对应的属性。字符串的来源(无论是从文件读取,还是从键盘输入等)可能已将 unicode 字符串编码为 ascii 以生成字符串,但这就是您需要寻找答案的地方。

也许您可能会问的问题是:“这个字符串是用 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"

解决方案 2:

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

解决方案 3:

Python 3.7 中的新功能(bpo32677)

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

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

解决方案 4:

在 Python 3 中,我们可以将字符串编码为 UTF-8,然后检查长度是否保持不变。如果是,则原始字符串为 ASCII。

def isascii(s):
    """Check if the characters in string s are in ASCII, U+0-U+7F."""
    return len(s) == len(s.encode())

为了检查,请传递测试字符串:

>>> isascii("♥O◘♦♥O◘♦")
False
>>> isascii("Python")
True

解决方案 5:

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

解决方案 6:

您的问题不正确;您看到的错误不是由您构建 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 词汇表可以作为理解其中一些问题的有用指南,它指出每个特定术语如何指代文本表示的不同部分,而这比许多程序员意识到的要复杂得多。

解决方案 7:

最近遇到了类似的事情 - 以供将来参考

import chardet

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

您可以将其与以下对象一起使用:

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

解决方案 8:

这样做怎么样?

import string

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

解决方案 9:

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

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

如果你遇到一个粗鲁而执着的人

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

特别是在进行编码时,请确保您没有尝试对已经是unicode的字符串进行unicode() - 由于某些可怕的原因,您会收到ascii编解码器错误。(另请参阅Python Kitchen食谱和Python文档教程,以更好地了解这有多么糟糕。)

最终我决定我想做的事情是:

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

将文件中的默认编码设置为 utf-8(将其放在 python 文件的开头)也有助于调试:

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

这样您就可以测试特殊字符('àéç'),而不必使用其 Unicode 转义符(u'àéç')。

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

解决方案 10:

为了改进 Alexander 在 Python 2.6(以及 Python 3.x)中的解决方案,您可以使用辅助模块 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)

解决方案 11:

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

解决方案 12:

Python 中的字符串 ( str-type) 是一系列字节。仅从字符串来看,无法判断这一系列字节是代表 ASCII 字符串、8 位字符集(如 ISO-8859-1)的字符串,还是用 UTF-8 或 UTF-16 或其他编码的字符串。

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

解决方案 13:

与@RogerDahl 的答案find_all类似,但通过否定字符类并使用搜索而不是或来进行短路更有效match

>>> 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

我想象正则表达式已经针对这一点进行了很好的优化。

解决方案 14:

import re

def is_ascii(s):
    return bool(re.match(r'[x00-x7F]+$', s))

要将空字符串包含为 ASCII,请将 更改+*

解决方案 15:

为了防止代码崩溃,你可能需要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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用