Pythonの文字列がASCIIであるかどうかを確認するにはどうすればよいですか?
質問
文字列がASCIIかどうかを確認したい。
ord()
を認識していますが、 ord( 'é')
を試すと、 TypeError:ord()が期待されます文字ですが、長さ2の文字列が見つかりました
。 Pythonのビルド方法が原因であると理解しました( ord()で説明しています)
のドキュメント)。
チェックする別の方法はありますか?
解決
def is_ascii(s):
return all(ord(c) < 128 for c in s)
他のヒント
あなたは正しい質問をしていないと思う-
Pythonの文字列には、「ascii」、utf-8、またはその他のエンコーディングに対応するプロパティがありません。文字列のソース(ファイルから読み取るか、キーボードから入力するかなど)は、文字列を生成するために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の方法:
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
Python 3.7の新機能( bpo32677 )
文字列の面倒な/非効率的なASCIIチェックはもう必要ありません。新しい組み込みの str
/ bytes
/ bytearray
メソッド- .isascii()
は、文字列がASCIIかどうかを確認します。
print("is this ascii?".isascii())
# True
最近このようなものを試しました-将来の参考のために
import chardet
encoding = chardet.detect(string)
if encoding['encoding'] == 'ascii':
print 'string is in ascii'
これは以下で使用できます:
string_ascii = string.decode(encoding['encoding']).encode('ascii')
あなたの質問は間違っています。表示されるエラーは、Pythonのビルド方法の結果ではなく、バイト文字列とUnicode文字列の混乱によるものです。
バイト文字列(Python構文では&quot; foo&quot;または 'bar'など)はオクテットのシーケンスです。 0〜255の数字。 Unicode文字列(u&quot; foo&quot;やu'bar 'など)は、Unicodeコードポイントのシーケンスです。 0〜1112064の数字。しかし、あなたは文字に興味があるように見えます&#233;(あなたの端末では)は単一の文字を表すマルチバイトシーケンスです。
ord(u '&#233;')
の代わりに、これを試してください:
>>> [ord(x) for x in u'é']
これにより、どのコードポイントのシーケンス&quot;&#233;&quot;がわかります。表します。 [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
。
Unicodeの用語集は、これらの問題のいくつかを理解するのに役立つガイドです。用語は、テキスト表現の別の部分を指します。これは、多くのプログラマが理解するよりもはるかに複雑です。
これを行うのはどうですか?
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で非推奨になりました。Python3では、 str.encode
で同じテストを行うことができます:
try:
mystring.encode('ascii')
except UnicodeEncodeError:
pass # string is not ascii
else:
pass # string is ascii
キャッチする例外も UnicodeDecodeError
から UnicodeEncodeError
に変更されていることに注意してください。
エンコードが不明な文字列の使用/エンコード/デコード方法(およびその文字列の特殊文字をエスケープ/変換する方法)を決定しようとしたときにこの質問を見つけました。
最初のステップは、文字列の型をチェックすることでした。型からその書式設定に関する適切なデータを取得できることに気付いていませんでした。 この回答は非常に役に立ち、私の問題の本当の根源になりました。
失礼で永続的な場合
UnicodeDecodeError: 'ascii'コーデックは、位置263のバイト0xc3をデコードできません:序数が範囲(128)にありません
特にエンコードするときは、すでにUnicodeである文字列をunicode()しようとしていないことを確認してください。何らかの恐ろしい理由で、ASCIIコーデックエラーが発生します。 ( Pythonキッチンレシピ、および Pythonのドキュメントこれがいかに恐ろしいのかをよりよく理解するためのチュートリアル。
やがて、やりたいことはこれだと判断しました:
escaped_string = unicode(original_string.encode('ascii','xmlcharrefreplace'))
デバッグで役立つのは、私のファイルのデフォルトのコーディングをutf-8に設定することです(これをpythonファイルの先頭に置きます):
# -*- coding: utf-8 -*-
これにより、Unicodeエスケープ(u '\ xe0 \ xe9 \ xe7')を使用せずに特殊文字( '&#224;&#233;&#231;')をテストできます。
>>> 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またはその他。
ただし、使用されているエンコーディングがわかっている場合は、strをUnicode文字列に decode
し、正規表現(またはループ)を使用して、範囲外の文字が含まれているかどうかを確認できます心配している。
@RogerDahlの回答と同様ですが、文字クラスを無効にして検索の代わりに< code> 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
このために正規表現が最適化されていると思います。
コードのクラッシュを防ぐには、 TypeErrors
try-except
を使用することをお勧めします
>>> 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
import re
def is_ascii(s):
return bool(re.match(r'[\x00-\x7F]+
空の文字列をASCIIとして含めるには、 +
を *
に変更します。
, s))
空の文字列をASCIIとして含めるには、 +
を *
に変更します。
次を使用して、文字列が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