質問するログイン新規登録
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

1454閲覧

[Python][Tkinter]Entryに実数のみ入力可能にしたい。

ohanabatake

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/07/24 04:45

0

0

実現したいこと

Entryに入力できる値を実数のみにしたいです。
実数は、正負,整数,浮動小数点数,10の累乗,e指数表記,0省略としたいです。

該当のソースコード

python

1import tkinter as tk 2import re 3 4class Application(tk.Frame): 5 entry = None 6 7 def onValidate(self, S): 8 if re.match(re.compile('[+-]?(?:\d+\.?\d*|\.\d+)(?:(?:[eE][+-]?\d+)|(?:\*10\^[+-]?\d+))?'), str(S)): 9 return True 10 else: 11 self.bell() 12 return False 13 14 def __init__(self, master=None): 15 super().__init__(master) 16 self.master.geometry("300x200") 17 frame = tk.Frame(self.master) 18 frame.pack() 19 20 vcmd = self.register(self.onValidate) 21 self.var = tk.DoubleVar(value='') 22 self.entry = tk.Entry(frame, width=15, textvariable=self.var, validate="key", validatecommand=(vcmd, '%S')) 23 self.entry.pack() 24 25if __name__ == "__main__": 26 root = tk.Tk() 27 app = Application(master=root) 28 app.mainloop()

試したこと

当たり前ですが、\d+で1個以上となっていることが、問題と思い\d?とすると、すべての文字が使用可能となってしまいました。
入力した値の先頭にmatchしている(と理解しています)ので、|を用いて記載した場合は、小数点.やeが好きなだけかけてしまい期待した結果にできませんでした。

補足情報

プログラミング学習を始めて1か月に満たないので、お手数ですがわかりやすく説明いただきたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TakaiY

2023/07/24 05:07

質問のコードの何が問題なのですか? 「\d+で1個以上となっていることが、問題と思い」の「問題」の部分です。
odataiki

2023/07/24 08:28

上のコメント通り、質問文を修正するのが良いと思います。 恐らくですが、「問題」=「期待通りの動きにならない原因」ということだと推察します。 また、(正規表現で入力制御を実装するなら)これは正規表現の課題と思いますので 質問文のタグに「正規表現」をつけるとより回答が集まりやすくなると思います。
ikedas

2023/07/25 08:56

回答に書いた通り、re.match()だと前方一致なので、後ろに関係ないものがあってもマッチが成功します。\d+を\d?に変えると「0文字または1文字の数字」に前方一致するので、結局「すべての文字が使用可能」になってしまうというわけですね。
guest

回答2

0

とりあえず実装するだけなら以下のようにすればよいかと。

python

1def onValidate(self, s): 2 s += '0' 3 try: 4 float(s) 5 return True 6 except: 7 return False

float関数で文字列から数値(浮動小数)に変換する際に不正な文字列はエラーが出ることを利用します。末尾に'0'を追加するのは'-'や'E'などの入力時にエラーを出さないためです。
この場合は判定には入力されている全文字列'%P'が必要です。

python

1self.entry = tk.Entry(frame, width=15, textvariable=self.var, validate="key", validatecommand=(vcmd, '%P'))

全パターンは調べていませんがざっと動作確認した感じでは大丈夫だと思います。

投稿2024/09/06 09:08

EMLauncher

総合スコア2

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Pythonの標準ライブラリを使うときは、公式ドキュメントでライブラリの仕様を確認する習慣をつけるとよいです。「re - 正規表現操作」を見てみましょう。

順に読んでいくと、「モジュールコンテンツ」に、このライブラリによって利用できるようになる関数が載っています。

  • re.search()は「string を走査し、正規表現 pattern がマッチを生じさせる最初の場所を探して、対応する マッチオブジェクト を返します」ということなので、中間一致です。ですから文字列中のマッチさせたいパターン (今回は数値) の前や後になにか余分なものがあってもマッチしてしまいます。それをさせないためには、正規表現の前後に「^」や「$」を置く必要があるでしょう。
  • re.match()は「string の先頭で 0 個以上の文字が正規表現 pattern にマッチすれば、対応する マッチオブジェクト を返します」ということなので、前方一致です。ですから文字列中のマッチさせたいパターンの後になにか余分なものがあってもマッチしてしまいます。それをさせないためには、正規表現の最後に「$」を置く必要があるでしょう。
  • re.fullmatch()は「string 全体が正規表現 pattern にマッチするなら、対応する マッチオブジェクト を返します」ということなので、完全一致です。ですから文字列がマッチさせたいパターンだけから成り、前や後に何もないときだけマッチします。

このように、使う関数によって正規表現に変更が必要ですね。


ところで、複雑な正規表現を記述するときはre.VERBOSEフラグを使うと便利です。このフラグをつけると正規表現中の改行や空白 (文字クラス中の空白などは除く) はすべて無視され、さらに各行の#以降もコメントとして無視されます。

python

1re.compile(r""" 2 [+-]? # 正負の符号 3 (?: \d+ \.? \d* | \. \d+ ) # 実数、0省略 4 (?: 5 (?: [eE] [+-]? \d+ ) # e指数表記 6 | (?: \* 10 \^ [+-]? \d+ ) # 10の累乗 7 )? 8""", re.VERBOSE)

python

1re.compile(r"[+-]?(?:\d+\.?\d*|\.\d+)(?:(?:[eE][+-]?\d+)|(?:\*10\^[+-]?\d+))?")

と同じです (すみません。上記は質問者さんのコードをもとに作成したつもりですが、動作確認していませんので、正しく動作しなかったら指摘ください)。

コメントまで入れられるので、とてもわかりやすくなります。

投稿2023/07/25 08:01

編集2023/07/25 08:10
ikedas

総合スコア4441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問