文字列がASCIIにあるかどうかを確認します。
ord()
を知っていますが、ord('é')
を試してみるとTypeError: ord() expected a character, but string of length 2 found
があります。 Pythonの作成方法が原因であると理解しました( ord()
のドキュメント で説明されています)。
チェックする別の方法はありますか?
def is_ascii(s):
return all(ord(c) < 128 for c in s)
あなたは正しい質問をしていないと思う-
pythonの文字列には、 'ascii'、utf-8、またはその他のエンコーディングに対応するプロパティがありません。文字列のソース(ファイルから読み取るか、キーボードから入力するかなど)は、文字列を生成するためにASCII文字列をUnicode文字列にエンコードしている場合がありますが、答えを見つける必要があります。
おそらくあなたが尋ねることができる質問は:「この文字列はASCII文字列をASCIIでエンコードした結果ですか?」 -これを試して答えることができます:
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の方法:
isascii = lambda s: len(s) == len(s.encode())
チェックするには、テスト文字列を渡します:
str1 = "♥O◘♦♥O◘♦"
str2 = "Python"
print(isascii(str1)) -> will return False
print(isascii(str2)) -> will return True
最近このようなものに走った-将来の参考のために
import chardet
encoding = chardet.detect(string)
if encoding['encoding'] == 'ascii':
print 'string is in ascii'
以下で使用できます:
string_ascii = string.decode(encoding['encoding']).encode('ascii')
文字列の面倒な/非効率的なASCIIチェックはもう必要ありません。新しい組み込みstr
/bytes
/bytearray
メソッド- .isascii()
は、文字列がasciiかどうかをチェックします。
print("is this ascii?".isascii())
# True
あなたの質問は間違っています。表示されるエラーは、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'
この文字は実際には、単一または複数のユニコード「コードポイント」のいずれかで表される場合があり、それ自体が書記素または文字のいずれかを表します。 「鋭アクセント付きe(コードポイント233)」または「e」(コードポイント101)の後に「前の文字の鋭アクセント」(コードポイント770)が続きます。したがって、このまったく同じ文字がPythonデータ構造体u'e\u0301'
またはu'\u00e9'
として表示される場合があります。
ほとんどの場合、これを気にする必要はありませんが、Unicode文字列を反復処理している場合は、分解可能な文字ではなくコードポイントによって反復処理が行われるため、問題になる可能性があります。つまり、len(u'e\u0301') == 2
およびlen(u'\u00e9') == 1
です。これが問題になる場合は、 unicodedata.normalize
を使用して、合成形式と分解形式を変換できます。
The Unicode Glossary は、各特定の用語がテキスト表現の異なる部分をどのように参照するかを指摘することにより、これらの問題のいくつかを理解するための有用なガイドとなります。
これはどうですか?
import string
def isAscii(s):
for c in s:
if c not in string.ascii_letters:
return False
return True
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
に変更されていることに注意してください。
エンコードがわからない文字列の使用/エンコード/デコードの方法(およびその文字列の特殊文字をエスケープ/変換する方法)を決定しようとしたときにこの質問を見つけました。
私の最初のステップは、文字列のタイプをチェックすることだったはずです-私はそこから、そのフォーマットに関する良いデータをタイプから取得できることに気づきませんでした。 この回答は非常に役に立ち、私の問題の本当の根本に到達しました。
失礼で執persistentになったら
UnicodeDecodeError: 'ascii'コーデックは、位置263のバイト0xc3をデコードできません:順序が範囲外(128)
特にエンコードするときは、すでにIS unicodeである文字列をunicode()しようとしていないことを確認してください。何らかの恐ろしい理由で、ASCIIコーデックエラーが発生します。 (これがどれほどひどいものであるかについてのより良い理解のために Python Kitchenレシピ と Python docs チュートリアルも参照してください。)
最終的に私がやりたいことはこれだと判断しました:
escaped_string = unicode(original_string.encode('ascii','xmlcharrefreplace'))
また、デバッグに役立つのは、私のファイルのデフォルトコーディングをutf-8に設定することです(これをpythonファイルの先頭に配置します)。
# -*- coding: utf-8 -*-
これにより、ユニコードエスケープ(u '\ xe0\xe9\xe7')を使用せずに特殊文字( 'àéç')をテストできます。
>>> specials='àéç'
>>> specials.decode('latin-1').encode('ascii','xmlcharrefreplace')
'àéç'
Python 2.6(およびPython 3.x)からAlexanderのソリューションを改善するには、ヘルパーモジュール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)
Posix標準[[:ASCII:]]定義を受け入れる正規表現ライブラリを使用できます。
Pythonの文字列(str
- type)は一連のバイトです。 方法はありませんこの一連のバイトがASCII文字列、ISO-8859-1のような8ビット文字セットの文字列、またはUTF-でエンコードされた文字列を表すかどうかを文字列を見ただけで判断します8またはUTF-16または何でも。
ただし、使用されているエンコーディングがわかっている場合は、decode
strをUnicode文字列に入れてから、正規表現(またはループ)を使用して、対象範囲外の文字が含まれているかどうかを確認できます。
@RogerDahlの answer と同様ですが、文字クラスを無効にし、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
このために正規表現が最適化されていると思います。
import re
def is_ascii(s):
return bool(re.match(r'[\x00-\x7F]+$', s))
空の文字列をASCIIとして含めるには、+
を*
に変更します。
コードがクラッシュしないようにするには、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