240

文字列がASCIIであるかどうかを確認したい。

私は知っていますord()、しかし、私が試みるときord('é')、私は持っていTypeError: ord() expected a character, but string of length 2 foundます。私はそれが私がPythonを構築した方法によって引き起こされていることを理解しました(ord()のドキュメントで説明されているように)。

確認する別の方法はありますか?

4

16 に答える 16

276

私はあなたが正しい質問をしていないと思います-

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"
于 2008-10-13T00:30:32.367 に答える
220
def is_ascii(s):
    return all(ord(c) < 128 for c in s)
于 2008-10-13T00:30:43.257 に答える
174

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
于 2013-08-23T13:14:49.313 に答える
28

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

于 2015-09-02T15:45:04.567 に答える
18

あなたの質問は間違っています。表示されるエラーは、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'

この文字は、実際には 1 つまたは複数の Unicode の「コード ポイント」で表すことができ、それ自体が書記素または文字を表します。それは、「アキュート アクセント付きの e (つまり、コード ポイント 233)」、または「e」 (コード ポイント 101) の後に「前の文字のアキュート アクセント」 (コード ポイント 770) が続きます。したがって、このまったく同じ文字が Python データ構造u'e\u0301'またはu'\u00e9'.

ほとんどの場合、これを気にする必要はありませんが、Unicode 文字列を反復処理する場合、反復は分解可能な文字ではなくコード ポイントで機能するため、問題になる可能性があります。つまり、len(u'e\u0301') == 2len(u'\u00e9') == 1. これが重要な場合は、 を使用して合成フォームと分解フォームを変換できますunicodedata.normalize

Unicode Glossaryは、多くのプログラマーが認識しているよりもはるかに複雑なテキスト表現の異なる部分を特定の用語がどのように参照しているかを指摘することで、これらの問題のいくつかを理解するための役立つガイドとなります。

于 2008-10-14T07:36:59.590 に答える
18

最近、このようなことに遭遇しました-将来の参考のために

import chardet

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

あなたが使用できる:

string_ascii = string.decode(encoding['encoding']).encode('ascii')
于 2011-08-08T20:47:22.390 に答える
9

エンコードが不明な文字列を使用/エンコード/デコードする方法(およびその文字列内の特殊文字をエスケープ/変換する方法)を決定しようとしたときに、この質問を見つけました。

私の最初のステップは、文字列の型をチェックすることでした。そこで、型からそのフォーマットに関する適切なデータを取得できることに気づいていませんでした。 この答えは非常に役に立ち、私の問題の本当の根源に到達しました。

失礼で執拗になっている場合

UnicodeDecodeError:'ascii'コーデックは位置263のバイト0xc3をデコードできません:序数が範囲(128)にありません

特にエンコードしているときは、すでにユニコードになっている文字列をユニコード()しようとしていないことを確認してください。何らかのひどい理由で、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')
'&#224;&#233;&#231;'
于 2012-08-21T23:24:35.620 に答える
9

これを行うのはどうですか?

import string

def isAscii(s):
    for c in s:
        if c not in string.ascii_letters:
            return False
    return True
于 2008-10-13T16:38:25.517 に答える
2

Posix標準の[[:ASCII:]]定義を受け入れる正規表現ライブラリを使用できます。

于 2008-10-13T00:18:25.560 に答える
2

Python の文字列( str-type) は、一連のバイトです。文字列を見るだけでは、この一連のバイトが ASCII 文字列、ISO-8859-1 のような 8 ビット文字セットの文字列、または UTF-8 や UTF-16 などでエンコードされた文字列を表しているかどうかを判断する方法はありません。 .

ただし、使用されているエンコーディングがわかっている場合はdecode、str を Unicode 文字列に変換し、正規表現 (またはループ) を使用して、懸念している範囲外の文字が含まれているかどうかを確認できます。

于 2008-10-14T07:58:08.173 に答える
1

@RogerDahlの回答find_allと同様ですが、文字クラスを否定し、 orの代わりに検索を使用して短絡する方が効率的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

これには正規表現が最適化されていると思います。

于 2016-10-28T16:30:33.790 に答える
-2

コードがクラッシュするのを防ぐために、 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
于 2013-07-07T21:16:00.113 に答える
-5

以下を使用して、文字列が 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
于 2010-07-21T06:34:56.927 に答える