isdecimalメソッドを使って、文字列が数字だけで構成されているかどうかを判定する方法を紹介。isdigit/isnumericメソッドとの違いも取り上げる。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
# 文字列が半角10進数字のみで構成されているかどうかを判定する関数
def isascnum(s):
return True if s.isdecimal() and s.isascii() else False
s1, s2, s3 = '123', '123', '123foo'
r1 = isascnum(s1)
r2 = isascnum(s2)
r3 = isascnum(s3)
print(f'{s1} isascnum: {r1}') # 123 isascnum: True
print(f'{s2} isascnum: {r2}') # 123 isascnum: False
print(f'{s3} isascnum: {r3}') # 123foo isascnum: False
# 文字列が10進数字のみで構成されているかどうかを判定
s1, s2, s3 = '123', '123', '123foo'
r1 = s1.isdecimal()
r2 = s2.isdecimal() # 全角数字はTrueとなる
r3 = s3.isdecimal()
print(f'{s1} isdecimal: {r1}') # 123 isdecimal: True
print(f'{s2} isdecimal: {r2}') # 123 isdecimal: True
print(f'{s3} isdecimal: {r3}') # 123foo isdecimal: False
s1, s2 = '-1', '1.23'
r1 = s1.isdecimal() # 符号が入っているとFalse
r2 = s2.isdecimal() # 小数点が入っているとFalse
print(f'{s1} isdecimal: {r1}') # -1 isdecimal: False
print(f'{s2} isdecimal: {r2}') # 1.23 isdecimal: False
# isdecimal/isdigit/isnumericメソッドの違い
s = '123' # 10進数字は全てTrue
r1 = s.isdecimal()
r2 = s.isdigit()
r3 = s.isnumeric()
print(f'{s} isdecimal: {r1}') # 123 isdecimal: True
print(f'{s} isdigit: {r2}') # 123 isdigit: True
print(f'{s} isnumeric: {r3}') # 123 isnumeric: True
s = '\u00b9\u00b2\u00b3' # 上付き数字の1、2、3はisdigit/isnumericではTrue
r1 = s.isdecimal()
r2 = s.isdigit()
r3 = s.isnumeric()
print(f'{s} isdecimal: {r1}') # 123 isdecimal: False
print(f'{s} isdigit: {r2}') # 123 isdigit: True
print(f'{s} isnumeric: {r3}') # 123 isnumeric: True
s = '二億四千万' # 漢数字などはisnumericでのみTrue
r1 = s.isdecimal()
r2 = s.isdigit()
r3 = s.isnumeric()
print(f'{s} isdecimal: {r1}') # 二億四千万 isdecimal: False
print(f'{s} isdigit: {r2}') # 二億四千万 isdigit: False
print(f'{s} isnumeric: {r3}') # 二億四千万 isnumeric: True
文字列のisdecimalメソッドを使うと、その文字列が10進数字のみで構成されているかどうかを判定できる。
以下に例を示す。
s1, s2, s3 = '123', '123', '123foo'
r1 = s1.isdecimal()
r2 = s2.isdecimal() # 全角数字はTrueとなる
r3 = s3.isdecimal()
print(f'{s1} isdecimal: {r1}') # 123 isdecimal: True
print(f'{s2} isdecimal: {r2}') # 123 isdecimal: True
print(f'{s3} isdecimal: {r3}') # 123foo isdecimal: False
ただし、上記例を見ると分かるが、全角数字のみで構成される文字列'123'についてもisdecimalメソッドはTrueを返す。このメソッドは、UnicodeのGeneral_Categoryプロパティの値が'Nd'であるものを10進数字として判定するようになっているからだ(Unicode Consortiumが提供しているUnicodeData.txtファイル)の3番目のフィールドを参照)。これらの数字はint関数で整数値に変換可能でもある。
このため、文字列が半角数字だけを含んでいるかどうかを知りたいときには、isasciiメソッドを組み合わせる必要がある。
s = '123'
if s.isdecimal() and s.isascii():
print(f'{s} includes only ASCII digits')
else:
print(f'{s} includes decimal characters')
# 出力結果:
# 123 include decimal characters
これらを組み合わせて以下のような関数を定義してもよいだろう。
def isascnum(s):
return True if s.isdecimal() and s.isascii() else False
s1, s2, s3 = '123', '123', '123foo'
r1 = isascnum(s1)
r2 = isascnum(s2)
r3 = isascnum(s3)
print(f'{s1} isascnum: {r1}') # 123 isascnum: True
print(f'{s2} isascnum: {r2}') # 123 isascnum: False
print(f'{s3} isascnum: {r3}') # 123foo isascnum: False
注意点としては、isdecimalメソッドは符号や小数点を含んだ文字列に対してはFalseを返すことが挙げられる。
s1 = '-12'
s2 = '1.23'
r1, r2 = s1.isdecimal(), s2.isdecimal()
print(f'{s1} isdecimal: {r1}') # -12 isdecimal: False
print(f'{s2} isdecimal: {r2}') # 1.23 isdecimal: False
符号や小数点を含んだ文字列を数値に変換できるかどうかを判定する方法については「[解決!Python]文字列が数値へ変換可能かどうかを判定するには(int/float関数の例外、re.fullmatch関数)」を参照されたい。
通常は上で述べたisdecimalメソッドを使えば、おおよそ10進数字として扱われるものを判定できる。しかし、Pythonの文字列にはisdigitメソッドとisnumericメソッドの2つのメソッドがある。isdecimalメソッドを含むこれら3つのメソッドの違いを以下にまとめる。
メソッド | 説明 |
---|---|
isdecimalメソッド | UnicodeのGeneral_Categoryプロパティの値がNdのものをTrueとする(UnicodeのNumeric_Typeプロパティの値がDecimalのものをTrueとする) |
isdigitメソッド | UnicodeのNumeric_Typeプロパティの値がDigit/DecimalのものをTrueとする |
isnumeircメソッド | UnicodeのNumeric_Typeプロパティの値がDigit/Decimal/NumericのものをTrueとする |
isdecimal/isdigit/isnumericメソッドの違い |
なお、UnicodeのGeneral_Category=Ndである文字とNumeric_Type=Decimalである文字は同一といってよさそうであることから、上のisdecimalメソッドの説明にはその旨を記載してある(「UNICODE CHARACTER DATABASE」の「UCD File Format Invariants」項が始まる直前の段落には「the set of characters having General_Category=Nd will always be the same as the set of characters having NumericType=de」とある)。
Copyright© Digital Advantage Corp. All Rights Reserved.