1

これが重複していたらごめんなさい。私は私の質問を少し言い直そうと思いました。

正規表現を使用して数式を評価するにはどうすればよいですか? eval 関数を使用しない場合。

式の例:

math1 = "1+1"
math2 = "3+2-1"

例で示したように、式の可変数の数値に対して機能するようにしたいと思います。

4

4 に答える 4

1

これは少し遅れていますが、任意の数式を評価するための gem を作成しました (内部で eval を使用していません): https://github.com/rubysolo/dentaku

于 2014-02-06T13:49:53.723 に答える
0

これは本当に厄介です…</p>

  math2 = "12+3-4"
  head, *tail = math2.scan(/(?<digits>\d+)(?<op>[\+\-\*\/])?/)
  .map{|(digits,op)| 
    [digits.to_i,op]
  }
  .reverse

  tail.inject(head.first){|sum,(digits,op)|
    op.nil? ? 
      digits : 
      digits.send(op,sum) 
    }
  # => 11

ただし、パーサーを検討する必要があります。

于 2013-04-14T00:58:42.020 に答える
0

加算と減算の場合、これは機能するはずです

(?:(/d+)([-+]))+(/d+)

これの意味は:

  • 1 つ以上の数字の後に 1 つのプラスまたはマイナスが続く
  • 上記は必要に応じて何度でも繰り返すことができます (これは非キャプチャ グループです)。
  • 1 つ以上の数字で終わる必要があります。

個々の数字と記号はそれぞれグループ 1..n でキャプチャされることに注意してください。

したがって、評価するには、キャプチャ 1 と 3 を取得し、キャプチャ 2 の符号を適用します。次に、キャプチャ 4 の​​符号 (存在する場合) を前の結果とキャプチャ 5 の数値 (キャプチャ 4 が存在する場合は存在する必要があります) に適用します。等々...

したがって、擬似コードで評価するには:

  i=1
  result=capture(i)
  loop while i <= (n-2) (where n is the capture count):
    If capture(i+1) == "-" // is subtraction 
       result = result - capture(i+2)
    Else // is addition 
       result = result + capture(i+2)
    End if
    i = i + 2
  End while

これは、左から右への結合性に依存しているため、提供した例のように単純な加算と減算でのみ機能します。他の人が示唆しているように、たとえば、正しい (深さ優先?) 順序で評価できるノードのツリーを構築するなど、より複雑なものを適切に解析する必要があるでしょう。

于 2013-04-14T00:28:59.860 に答える