正規表現を扱うためのreモジュールのfullmatch関数などを使用して、文字列が数字だけで構成されているかどうかを判定する方法を紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
# 文字列が半角の10進数字のみで構成されているかどうかを判定する関数の例
import re
def isonlynum(s):
return True if re.fullmatch('[0-9]+', s) else False
s1, s2 = '123', '123'
r1 = isonlynum(s1)
r2 = isonlynum(s2)
print(f'{s1}: {r1}, {s2}: {r2}') # 123: True, 123: False
# 正規表現を使って、文字列が半角の10進数字のみで構成されているかどうかを判定
import re
s1, s2 = '123', '123'
r1 = re.fullmatch('[0-9]+', s1) # 1文字以上の半角数字
r2 = re.fullmatch('[0-9]+', s2)
print(f'{s1}: {r1}') # 123: <re.Match object; span=(0, 3), match='123'>
print(f'{s2}: {r2}') # 123: None
r1 = re.fullmatch('\d+', s1, re.ASCII) # 1文字以上の10進数字+ASCIIの範囲内
r2 = re.fullmatch('\d+', s2, re.ASCII)
print(f'{s1}: {r1}') # 123: <re.Match object; span=(0, 3), match='123'>
print(f'{s2}: {r2}') # 123: None
# 文字列が全角を含む10進数字のみで構成されているかどうかを判定
s = '123'
result = re.fullmatch('\d+', s)
print(result) # <re.Match object; span=(0, 3), match='123'>
文字列が半角の(ASCIIに含まれる範囲の)10進数字のみで構成されているかどうかを判定するには正規表現を使える。あるいは文字列が持つ各種メソッドを使ってもよい。後者については「文字列が数字だけで構成されているかどうかを判定するには(isdecimal/isdigit/isnumeric/isasciiメソッド)」を参照されたい。
なお、符号や小数点を含んだ文字列を整数値または浮動小数点数値に変換できるかを判定する方法については「[解決!Python]文字列が数値へ変換可能かどうかを判定するには(int/float関数の例外、re.fullmatch関数)」を参照されたい。
reモジュールのfullmatch関数を使った例を以下に示す。
import re
s = '123'
result = re.fullmatch('[0-9]+', s) # 1文字以上の文字クラス[0-9]
print(result) # <re.Match object; span=(0, 3), match='123'>
result = re.fullmatch('\d+', s, re.ASCII)
print(result) # <re.Match object; span=(0, 3), match='123'>
s = '123foo'
result = re.fullmatch('[0-9]+', s)
print(result) # None
最初の例で使っている正規表現は、1文字以上の半角数字「0」〜「9」の並びを表す。re.fullmatch関数は第1引数に指定した正規表現(パターン)が文字列全体とマッチするかを調べるので、ここでは文字列の先頭や末尾を意味する「^」「$」「\A」「\Z」を省略している。
次の例で使用している文字クラス「\d」はUnicodeで10進数字を意味するGeneral_Categoryプロパティの値「Nd」を持っている文字全てにマッチする。そのため、re.ASCIIフラグをfullmatch関数の第3引数に指定することで、半角の数字のみマッチするようにしている(このフラグを指定しなければ、全角の10進数字などもマッチするようになる。後述)。
最後はマッチしなかった場合の例だ。
上のコードに示したように、マッチしたときにはre.Matchクラスのインスタンスが返送されるが、マッチしなかったときには何も返されない(None値が返される)。このことを使えば、if文で条件分岐したり、半角数字だけで構成されているかどうかを判定する関数を定義したりできるだろう。
s = '123foo'
if re.fullmatch('[0-9]+', s):
print(f'{s} includes only decimal numbers')
else:
print(f'{s} includes non decimal characters')
# 出力結果:
# 123foo includes non decimal characters
def isonlynum(s):
return True if re.fullmatch('[0-9]+', s) else False
s1, s2 = '123', '123'
r1 = isonlynum(s1)
r2 = isonlynum(s2)
print(f'{s1}: {r1}, {s2}: {r2}') # 123: True, 123: False
なお、reモジュールのmatch関数やsearch関数を使っても同様な判定は可能だ。
s = '123'
result = re.match('[0-9]+$', s)
print(result) # <re.Match object; span=(0, 3), match='123'>
result = re.search('\A[0-9]+\Z', s)
print(result) # <re.Match object; span=(0, 3), match='123'>
s = 'foo123bar456'
result = re.match('[0-9]+$', s)
print(result) # None
result = re.search('\A[0-9]+\Z', s)
print(result) # None
re.fullmatch関数は文字列全体をマッチの対象としたが、re.match関数は正規表現が文字列の先頭からマッチするかの判定を行い、re.search関数は文字列中の任意の位置に指定した正規表現とマッチする部分があるかを検索するという違いがある。このため、先ほどとは正規表現が少し異なっていることに注意しよう(先頭を表す「^」と「\A」および末尾を表す「$」と「\Z」を上の例では同様に取り扱っているが、マルチラインモードでマッチを行う際には振る舞いが少し変わってくる。これについては本稿では取り上げない)。文字列全体が数字で構成されているかを判定するということで、本稿ではre.fullmatch関数を優先して取り上げた。
ここまで読めば既に答えは出たも同じだが、全角数字「123」なども含めて、文字列が10進数字のみで構成されているかどうかを判定するには以下の正規表現が使える。
# 文字列が全角を含む10進数字のみで構成されているかどうかを判定
s = '123456789'
result = re.fullmatch('\d+', s)
print(result) # <re.Match object; span=(0, 9), match='123456789'>
re.fullmatch関数に正規表現として「\d」を渡して、第3引数でre.ASCIIフラグを指定しないようにすればよい。
Copyright© Digital Advantage Corp. All Rights Reserved.