現在、Pythonでユーザーが入力した複数の式の中から変数、定数(係数は除きます)のみを抽出することを考えています。
例えば、
y = sgn(Asin(x1+b))+bcos(max(x2,xt)+2*b)
といった式の中から
変数:x1、x2
定数:A、、b、xt
を取り出したいと考えています。
式を文字列として読み込んで、=、*、-、+、/,(、)等を区切り文字とし、関数名や数字を除けば良いかとも考えましたが、max関数やsin、cos、acos、cosh等、考えられる関数の数がかなり多く、ユーザーがどのような入力をするか分からないため、上記の方法では難しそうで、現在息詰まっております。(上式は一例で、実際にユーザーがどのような形で式を入力するかは様々なケースがあり得ます)
もう少し考えてみますが、良い案をお持ちの方がいらっしゃいましたら、アイディアだけでも構いませんので、ご教授いただければ幸いです。
宜しくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/07 11:33
回答7件
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/07 11:34
2018/06/07 12:07
0
ベストアンサー
正規表現版。
python
1import re 2 3s = 'y = sgn(A*sin(x1+b))+b*cos(max(x2,xt)+2*b)' 4 5funcs = {'sgn', 'sin', 'cos', 'tan', 'max', 'min'} 6 7items = set(filter(None, re.split(r'\W', s))) 8ans = items - funcs 9print(ans)
関数を列挙しない版。
python
1import re 2 3s = 'y = sgn(A*sin(x1+b))+b*cos(max(x2,xt)+2*b)' 4 5s = re.sub(r'[a-zA-Z]\w+(', '(', s) 6 7items = set(filter(None, re.split(r'\W', s))) 8 9items = [v for v in items if not re.match(r'^[0-9]', v)] 10 11print(items)
投稿2018/06/07 09:43
編集2018/06/07 10:03総合スコア8560
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/07 22:29
2018/06/08 00:35
2018/06/08 05:03
2018/06/08 05:45
0
- まず文字列全体から空白文字を削除する
y=sgn(Asin(x1+b))+bcos(max(x2,xt)+2*b)
- 連続するアルファベットの右側に'('があるパターンから関数名を検索して当該部分を削除する
y=(A*(x1+b))+b*((x2,xt)+2*b)
- 変数と定数以外(アルファベットと数字以外の文字)の文字をすべて空白にする
y A x1 b b x2 xt 2 b
- 一つ以上の連続する空白を ',' に置き換える
y,A,x1,b,b,x2,xt,2,b
こんな感じでできそうですがいかがでしょうか。
正規表現使えば各ステップは難しくないと思います。
なお、ユーザー定義関数だけ残したい場合は、予約語を辞書で持っておく必要があると思います。
また、変数と定数の区別については、命名規則がハッキリしていないと区別できないでしょう。
ご参考になれば。
投稿2018/06/07 08:40
総合スコア2425
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
例えば、こんな入力があったとします。
plain
1y = m(a+b)
これは、mという関数にa+bを与えているのでしょうか。
あるいは、mという値を、a+bの結果に掛け合わせようとしているのでしょうか。
これだけ見れば判別不可能です。
そして、ルールを増やす
これを防ぐために、『乗算記号の省略は認めない』というルールを作るとします。
先ほどの入力が、次のように修正されたとします。
plain
1y = m*(a+b)
この式のmは、変数でしょうか。あるいは、定数でしょうか。
また、aやbは絶対に定数であると、誰が保証してくれるのでしょうか。
これだけ見れば判別不可能です。
ユーザが定数と主張すればそれは定数でしょうし、変数と主張すればそれは変数です。
そして、ルールを増やす
変数は必ずx, y あるいは z から始まるとし、それ以外を定数とします。
y = sgn(Asin(x1+b))+bcos(max(x2,xt)+2*b)
といった式の中から
変数:x1、x2
定数:A、、b、xt
を取り出したいと考えています。
前述のルールに則ればxtは変数になってしまいます。
さて、どのように変数と定数を区別できるとお考えなのでしょうか。
とりあえず
区別したいのなら、最低限明確な命名規則を決めるべきかと思います。
また、利用可能な文字も制限する必要があります。
たとえば、log_10
という関数を許すか?などなど。
投稿2018/06/07 08:15
編集2018/06/07 08:21総合スコア35660
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/07 11:36
0
数式表現なんて人間が文脈を見て意味を判断する自然言語なので、はっきり言って式だけ入れてもまともに解析なんてできません。
- 変数名、定数名、関数名は先に宣言させる
という発想で挑まないと厳しいと思うのですが、そうする訳にはいきませんか。
逆に、そういう仕様にしてしまえば、組み込みで適当な名前を提供するとかは自由です。
いっそ「S式で入力してくれ」という話にはならないものか。
lisp
1(+ (sgn (* A 2 (sin (+ x1 b)))) 3 (* b 4 (cos (+ (max x2 xt) 5 (* 2 b))))) 6
投稿2018/06/07 10:44
総合スコア30933
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
投稿2018/06/07 08:22
編集2018/06/07 08:43総合スコア5572
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。