質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

895閲覧

正規表現で分数と演算子を分けたいです。

fjaiofjawiefjaw

総合スコア210

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/10/07 18:40

編集2017/10/07 18:56

文字列'(3/10)+(1/2)*(1/3)-(1/25)/(3/100)'
を引数にして逆ボーランド記法を使用して、答えを求めるプログラムを
作りたいと思っております。

配列で [分数, 演算子, 分数, 演算子]
というように分数と演算子で分けたいです。

javascript

1const str = '(3/10)+(1/2)*(1/3)-(1/25)/(3/100)'; 2var re = /(+|\-|*|/)/; 3var re2 = /(+|\-|*|[^\d]/)/; 4const splits = str.split(re); 5console.log(splits);

期待する出力は、
[(3/10),+,(1/2),*,(1/3),-,(1/25),/,(3/100)]
です。
数字に挟まれていないスラッシュが上手く表現できません。

一つ目の、reだと
分数と割り算のスラッシュが被ってしまいます。
2つ目の、re2だと下記リンクの様に ')/' が該当してしまいます。
https://regex101.com/r/JDiPz5/1

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

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

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

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

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

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

guest

回答2

0

括弧の入れ子を考慮しなくて良ければ、mio-c さんが提案されたコードで可能ですが、
(String#split でも書けますが、String#match の方が効率が良いです)

JavaScript

1const string = '(3/10)+(1/2)*(1/3)-(1/25)/(3/100)'; 2const splits = JSON.stringify(string.match(/(\d+/\d+)|[*/+-]/g)); 3alert(splits);

逆ボーランド記法を踏まえるなら、RegExp#exec で再帰処理するとスタックを積みやすく、括弧内の計算はマッチと共に処理出来ます。
左から順番にスタックを積むと、演算子の優先順位に対応出来ないので、*/+- よりも一段深いスタックにする処理が必要になります。
https://qiita.com/yumura_s/items/ddb0d143fb0e9a082891

Re: fjaiofjawiefjaw さん

投稿2017/10/08 07:26

think49

総合スコア18162

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

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

fjaiofjawiefjaw

2017/10/08 09:15

とても、詳しい回答ありがとうございます。 RegExp#execで再帰処理が出来るという所がとても気になりますので、後で調べてみます。 キータを見ましたが、難しいので、こちらも、勉強させて頂きます。 ありがとうございました。
guest

0

ベストアンサー

こんな感じでしょうか?
カッコ付きを優先してマッチさせて、次にそれ以外もマッチさせて配列にいれています。

js

1 var test = '(3/10)+(1/2)*(1/3)-(1/25)/(3/100)' 2 var match = test.match(/(.+?)|[+\-*/]/g) 3 console.log(match)

結果

(9) ["(3/10)", "+", "(1/2)", "*", "(1/3)", "-", "(1/25)", "/", "(3/100)"]

投稿2017/10/07 20:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

fjaiofjawiefjaw

2017/10/08 09:10

とても早い時間に回答頂きありがとうございました。 無理にsplitにこだわる必要は、無かったですね。 なぜ、クエスチョンマークがいるのか、分からないのですが、調べてみたいと思います。
退会済みユーザー

退会済みユーザー

2017/10/09 13:29 編集

think49さんの仰る通り入れ子を考慮していないので”カッコの中はなんでも良い”と指定してます。?は最短のマッチという意味です。”中身はなんでも良い”なので付けないと (aa)(bb)(cc) の最初の"("から最後の")"にマッチしてしまうわけですね…。 入れ子も踏まえて厳密にチェックするならthink49さんの書いているパターンが良いですね!
fjaiofjawiefjaw

2017/11/06 22:17

コメント返信頂いていたのを気づいておりませんでした。 詳しい解説、どうもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問