Pythonの文字列判定は、Unicodeに強く、数字や英字、空白の扱いも細かく分かれています。
本記事では数字・英字・空白の判定方法を、初心者にもわかりやすく段階を踏んで解説します。
isXXX系メソッドの違いやよくある誤判定のポイント、目的別の実用レシピまで一気にまとめます。
まずは基本のメソッドから確認しましょう。
Pythonの基本判定メソッド
数字判定(isdigit/isdecimal/isnumeric)
Pythonには数字を判定するために3種類の似たメソッドがあり、それぞれ判定範囲が異なります。
狭い順にisdecimal → isdigit → isnumericです。
英語表記の違いに惑わされず、適切なものを選ぶことが重要です。
str.isdecimal()
: 10進数字(0〜9や全角0〜9)のみをTrueにします。str.isdigit()
: 上記に加え、上付き数字(²)など「数字として数えられる文字」をTrueにします。str.isnumeric()
: さらにローマ数字(Ⅳ)、分数文字(⅕)、囲み数字(①)など「数値として解釈できる文字」を含みます。
代表例と結果を次の表で整理します。
例 | 説明 | isdecimal | isdigit | isnumeric |
---|---|---|---|---|
“123” | 半角の10進数字 | True | True | True |
“123” | 全角の10進数字 | True | True | True |
“²” | 上付きの2 | False | True | True |
“①” | 囲み数字1 | False | False | True |
“Ⅳ” | ローマ数字4 | False | False | True |
“⅕” | 分数1/5 | False | False | True |
“3.14” | 小数点含む | False | False | False |
“-42” | 符号付き | False | False | False |
“” | 空文字 | False | False | False |
実際に違いを確かめるコードを用意しました。
# 3つの数字判定メソッドの違いを確認するデモ
tests = ["123", "123", "²", "①", "Ⅳ", "⅕", "3.14", "-42", ""]
for s in tests:
# reprで見分けやすく表示
print(f"{repr(s):>6} -> isdecimal:{s.isdecimal():5} isdigit:{s.isdigit():5} isnumeric:{s.isnumeric():5}")
'123' -> isdecimal: True isdigit: True isnumeric: True
'123' -> isdecimal: True isdigit: True isnumeric: True
'²' -> isdecimal: False isdigit: True isnumeric: True
'①' -> isdecimal: False isdigit: False isnumeric: True
'Ⅳ' -> isdecimal: False isdigit: False isnumeric: True
'⅕' -> isdecimal: False isdigit: False isnumeric: True
'3.14' -> isdecimal: False isdigit: False isnumeric: False
'-42' -> isdecimal: False isdigit: False isnumeric: False
'' -> isdecimal: False isdigit: False isnumeric: False
電話番号や郵便番号のように「0〜9の並びだけ」を許容したいならisdecimalが最も安全です。
一方、数学記号的な数字も受け入れたいならisnumericを選びます。
- 関連記事:文字列と数値の型を変換したい
- 関連記事:整数 (int) と小数 (float) の計算方法
英字判定(isalpha)
str.isalpha()
は、英字だけでなく、Unicodeの「文字」全般を対象にします。
つまり、アクセント付き文字(é)やギリシャ文字(α)、ひらがな・カタカナ・漢字もTrueになります。
ASCIIのA〜Z、a〜zに限定したい場合はisalphaだけでは不十分です。
後述のisascii()
と組み合わせます。
# isalphaの挙動を確認
samples = ["Hello", "ABC", "Café", "こんにちは", "Hello123", ""]
for s in samples:
print(f"{s!r:>10} -> isalpha: {s.isalpha()}")
'Hello' -> isalpha: True
'ABC' -> isalpha: True
'Café' -> isalpha: True
'こんにちは' -> isalpha: True
'Hello123' -> isalpha: False
'' -> isalpha: False
空白判定(isspace)
str.isspace()
は空白類文字全般にTrueを返します。
半角スペースだけでなく、タブ(\t
)、改行(\n
)、復帰(\r
)、全角スペース(
)なども含みます。
# isspaceの挙動を確認
spaces = [" ", "\t\n", " ", " a "]
for s in spaces:
print(repr(s), "-> isspace:", s.isspace())
' ' -> isspace: True
'\t\n' -> isspace: True
' ' -> isspace: True
' a ' -> isspace: False
ASCII限定の確認(isascii)
str.isascii()
はASCII範囲(0〜127)かどうかを確認します。
英字や数字の判定と組み合わせると、ASCII限定の検査ができます。
# isasciiの確認
vals = ["ABC", "123", "Café", " "]
for s in vals:
print(f"{s!r:>8} -> isascii: {s.isascii()}")
'ABC' -> isascii: True
'123' -> isascii: False
'Café' -> isascii: False
' ' -> isascii: True
よくある誤判定と注意点
全角数字・全角英字の扱い
全角数字("123"
)はisdecimal/isdigit/isnumeric
のいずれもTrueになります。
一方、全角英字("ABC"
)はisalpha
にTrueですが、isascii
はFalseです。
表示が似ていても、ASCII限定の要件なら必ずisasciiで絞り込みます。
ローマ数字や分数はisnumericのみTrue
"Ⅳ"
や"⅕"
、"①"
はisnumeric()
だけがTrueです。
「数字っぽい」Unicode文字を許容するならisnumeric、許容しないならisdecimalを選びます。
空文字や記号が混ざるとFalse
isdecimal/isdigit/isnumeric/isalpha/isspace
は、空文字では必ずFalseです。
また"123,456"
や"Hello!"
のように対象外の記号が混ざるとFalseになります。
タブや改行も空白(isspace)に含まれる
画面に見えなくても、"\t"
や"\n"
は空白として扱われます。
「半角スペースのみ」を許したい場合はisspaceではなく正規表現などを使います。
符号や小数点を含む数はFalse
"-42"
や"3.14"
はどの数字判定メソッドでもFalseです。
数値として解釈したい場合はintやfloatでパースして検証します。
# よくある誤判定パターンの動作確認
cases = ["123,456", "Hello!", "-42", "3.14", "", " \t", " "]
for s in cases:
print(f"{s!r:>8} -> isdecimal:{s.isdecimal():5} isalpha:{s.isalpha():5} isspace:{s.isspace():5}")
'123,456' -> isdecimal: False isalpha: False isspace: False
'Hello!' -> isdecimal: False isalpha: False isspace: False
'-42' -> isdecimal: False isalpha: False isspace: False
'3.14' -> isdecimal: False isalpha: False isspace: False
'' -> isdecimal: False isalpha: False isspace: False
' \t' -> isdecimal: False isalpha: False isspace: True
' ' -> isdecimal: False isalpha: False isspace: True
- 関連記事:例外(Exception)入門
- 関連記事:try-exceptで例外処理を実装する
目的別の判定レシピ
文字列全体が数字だけか判定
10進数字のみ(0〜9や全角0〜9)を許容する場合はisdecimal()
を使います。
上付きやローマ数字も許容するならisdigit()
やisnumeric()
に切り替えます。
# 用途に応じて使い分けできる関数群
def is_decimal_digits(s: str) -> bool:
"""10進数字(0〜9と全角0〜9)のみ"""
return len(s) > 0 and s.isdecimal()
def is_digit_chars(s: str) -> bool:
"""数字として数えられる文字も含める(例: ²)"""
return len(s) > 0 and s.isdigit()
def is_numeric_chars(s: str) -> bool:
"""数値として解釈できる文字全般(例: ①, Ⅳ, ⅕ を含む)"""
return len(s) > 0 and s.isnumeric()
tests = ["123", "123", "²", "①", "Ⅳ", "⅕", "3.14", ""]
for s in tests:
print(f"{s!r:>6} dec:{is_decimal_digits(s):5} dig:{is_digit_chars(s):5} num:{is_numeric_chars(s):5}")
'123' dec: True dig: True num: True
'123' dec: True dig: True num: True
'²' dec: False dig: True num: True
'①' dec: False dig: False num: True
'Ⅳ' dec: False dig: False num: True
'⅕' dec: False dig: False num: True
'3.14' dec: False dig: False num: False
'' dec: False dig: False num: False
- 関連記事:文字列の長さを調べる
- 関連記事:文字列が特定の文字で始まる/終わるかを判定
文字列全体が英字だけか判定(ASCII/Unicode)
Unicodeの文字全般を許容するならisalpha()
だけで十分です。
ASCII限定ならisascii()
と組み合わせます。
def is_alpha_unicode(s: str) -> bool:
"""Unicodeの文字だけ(ひらがな・漢字・全角英字・ラテン拡張などもOK)"""
return len(s) > 0 and s.isalpha()
def is_alpha_ascii(s: str) -> bool:
"""ASCIIの英字だけ(A〜Z, a〜z)"""
return len(s) > 0 and s.isascii() and s.isalpha()
samples = ["Hello", "ABC", "Café", "こんにちは", "Hello123", ""]
for s in samples:
print(f"{s!r:>10} uni:{is_alpha_unicode(s):5} ascii:{is_alpha_ascii(s):5}")
'Hello' uni: True ascii: True
'ABC' uni: True ascii: False
'Café' uni: True ascii: False
'こんにちは' uni: True ascii: False
'Hello123' uni: False ascii: False
'' uni: False ascii: False
文字列全体が空白だけか判定
isspace()
でOKです。
ただし空文字はFalseなので、入力チェックで「空白のみ不可」を弾くのにも使えます。
def is_only_whitespace(s: str) -> bool:
"""空白(タブや改行、全角スペース含む)のみか"""
return len(s) > 0 and s.isspace()
tests = [" ", "\t\n", " ", "", " a "]
for s in tests:
print(f"{s!r:>6} -> {is_only_whitespace(s)}")
' ' -> True
'\t\n' -> True
' ' -> True
'' -> False
' a ' -> False
各文字を走査して種別を判定
文字列に数字・英字・空白・その他が混在する場合、1文字ずつ判定して分類できます。
ログの解析や入力の詳細な検査に便利です。
# 各文字の種別を判定して表示
def char_kind(ch: str) -> str:
# 1文字の性質をわかりやすく分類
if ch.isdecimal():
return "decimal"
if ch.isdigit():
return "digit"
if ch.isnumeric():
return "numeric"
if ch.isalpha():
return "alpha"
if ch.isspace():
return "space"
return "other"
s = "A1 ²①Ⅳ-Ω "
for i, ch in enumerate(s):
# reprで全角スペースなども視認しやすく
print(f"index={i:2}: {repr(ch):>4} -> {char_kind(ch)}")
index= 0: 'A' -> alpha
index= 1: '1' -> decimal
index= 2: ' ' -> space
index= 3: '²' -> digit
index= 4: '①' -> numeric
index= 5: 'Ⅳ' -> numeric
index= 6: '-' -> other
index= 7: 'Ω' -> alpha
index= 8: ' ' -> space
ASCIIの数字/英字/空白のみ許可(正規表現)
ASCIIの英数字と空白だけを許す場合は正規表現が明快です。
re.ASCII
フラグを使うと\s
などの文字クラスがASCIIに限定されます。
import re
# ASCIIの英数字と空白(タブ・改行なども含む)のみ
pat_ascii_alnum_space = re.compile(r'(?:[A-Za-z0-9]|\s)+\Z', flags=re.ASCII)
# 半角スペースだけを空白とみなす場合は、\sの代わりにスペース1個を使う
pat_ascii_alnum_space_only_space = re.compile(r'(?:[A-Za-z0-9]| )+\Z')
tests = [
"Hello World", # OK
"Line1\nLine2", # OK(ASCIIの改行含む)
"ABC123\tXYZ", # OK(タブ含む)
"ABC", # NG(全角)
"Café", # NG(éは非ASCII)
"Hello-World", # NG(ハイフンは許可外)
]
for s in tests:
ok1 = bool(pat_ascii_alnum_space.fullmatch(s))
ok2 = bool(pat_ascii_alnum_space_only_space.fullmatch(s))
print(f"{s!r:>14} -> ASCII空白含む: {ok1}, 半角スペースのみ空白: {ok2}")
'Hello World' -> ASCII空白含む: True, 半角スペースのみ空白: True
'Line1\nLine2' -> ASCII空白含む: True, 半角スペースのみ空白: False
'ABC123\tXYZ' -> ASCII空白含む: True, 半角スペースのみ空白: False
'ABC' -> ASCII空白含む: False, 半角スペースのみ空白: False
'Café' -> ASCII空白含む: False, 半角スペースのみ空白: False
'Hello-World' -> ASCII空白含む: False, 半角スペースのみ空白: False
ASCII以外を一切許したくないときはisascii()
で全体をチェックしてから、さらに正規表現で許可文字だけに絞ると堅牢になります。
- 関連記事:正規表現(re)入門
- 関連記事:re — 公式ドキュメント(ASCII フラグ)
選び方の指針
Unicode対応ならisXXX系
多言語や全角を扱うなら、isdecimal/isdigit/isnumeric・isalpha・isspaceなどのisXXX系が第一選択です。
要件に応じて判定範囲の広さを選びます。
- 厳格な10進数字のみ:
isdecimal()
- 上付きなどを含めた「数字」:
isdigit()
- ローマ数字・分数・囲み数字まで:
isnumeric()
- 文字全般(日本語含む):
isalpha()
- 空白全般(タブ・改行・全角含む):
isspace()
ASCII限定ならisasciiや正規表現
ASCIIだけを許可する要件なら、isascii()
と組み合わせるか、re.ASCII
フラグ付き正規表現で明示的に制御します。
isalphaだけでは全角・非ASCIIの文字も通る点に注意します。
入力バリデーションの注意点
現実の入力は複雑で、符号や小数点を含む数値や見た目が似た記号が混じることがあります。
数値として妥当かどうかを調べるなら、int()
やfloat()
でのパースを優先します。
また、Unicodeの見た目差を吸収したい場合は正規化も検討します。
# 数値の真偽は「パースできるか」で判定するのが堅実
def is_int_value(s: str) -> bool:
try:
int(s) # 先頭や末尾の空白は許可されません
return True
except ValueError:
return False
tests = ["42", "-42", " 42", "3.0", "3.14", "Ⅳ"] # Ⅳは数値風だがintは失敗
for s in tests:
print(f"{s!r:>4} -> int判定: {is_int_value(s)}")
'42' -> int判定: True
'-42' -> int判定: True
' 42' -> int判定: False
'3.0' -> int判定: False
'3.14' -> int判定: False
'Ⅳ' -> int判定: False
さらに、NFKC/NFKD正規化で「互換文字」を分解・変換すると、判定や検索の一貫性が上がる場合があります。
import unicodedata
samples = ["①", "Ⅳ", "²", "ABC"]
for s in samples:
nfkD = unicodedata.normalize("NFKD", s)
nfkC = unicodedata.normalize("NFKC", s)
print(f"{s!r} -> NFKD:{nfkD!r} NFKC:{nfkC!r}")
'①' -> NFKD:'1' NFKC:'1'
'Ⅳ' -> NFKD:'IV' NFKC:'IV'
'²' -> NFKD:'2' NFKC:'2'
'ABC' -> NFKD:'ABC' NFKC:'ABC'
正規化後にASCII限定の判定を行うことで、ユーザー入力の「見た目の差」を吸収しやすくなります。
ただし、要件に応じて正規化の可否を慎重に判断してください。
まとめ
本記事では、Pythonで文字列が数字/英字/空白かを判定する方法を体系的に解説しました。
数字の判定はisdecimal/isdigit/isnumericの順に許容範囲が広がる点、isalphaはUnicode全般の文字にTrueになる点、isspaceはタブや改行、全角スペースも含む点が核心です。
ASCII限定の要件ではisascii()
やre.ASCII
付き正規表現を組み合わせ、入力バリデーションではint/float
でのパースやunicodedata.normalize
による正規化も検討してください。
要件に最適な判定を選べば、誤判定や不正入力の取りこぼしを確実に減らせます。