正規表現を使用してリバース ポリッシュ計算機の問題を解決しようとしていますが、数式を従来の形式に変換する際に問題が発生しています。
私が書いた:
puts '35 29 1 - 5 + *'.gsub(/(\d*) (\d*) (\W)/, '(\1\3\2)')
これは次を印刷します:
35 (29-1)(+5) *
期待される
(35*((29-1)+5))
しかし、私は別の結果を得ています。私は何を間違っていますか?
正規表現を使用してリバース ポリッシュ計算機の問題を解決しようとしていますが、数式を従来の形式に変換する際に問題が発生しています。
私が書いた:
puts '35 29 1 - 5 + *'.gsub(/(\d*) (\d*) (\W)/, '(\1\3\2)')
これは次を印刷します:
35 (29-1)(+5) *
期待される
(35*((29-1)+5))
しかし、私は別の結果を得ています。私は何を間違っていますか?
私はあなたがしようとしたことを意味していると思います
puts '35 29 1 - 5 + *'.gsub(/(\d*) (\d*) (\W)/, '(\1\3\2)')
^ ^
とにかく、+
代わりに量指定子を使用する必要があります。そうしないと、キャプチャの 1 つとして*
空の文字列に一致するため、次のようになります。\d*
(+5)
/(\d+) (\d+) (\W)/
式を次のようにさらに拡張/制約します。
/([\d+*\/()-]+)\s+([\d+*\/()-]+)\s+([+*\/-])/
| | | | |
| | | | Valid operators, +, -, *, and /.
| | | |
| | | Whitespace.
| | |
| | Arbitrary atom, e.g. "35", "(29-1)", "((29-1)+5)".
| |
| Whitepsace.
|
Arbitrary atom, e.g. "35", "(29-1)", "((29-1)+5)".
...そして を使用する代わりに、これ以上置換を行うことができないことを検出したときに終了するループでgsub
使用します。そうしないと、操作の順序に違反するため、これは非常に重要です。たとえば、この Rubular demoを見てください。を使用すると、最初のトライアドを置換した後に実際には 2 番目の反復で「以前の」トライアドを置換する必要があるときに、アトムの 2 番目のトライアド「5 + *」を置換する可能性があることがわかります。sub
while
gsub
警告: (-
マイナス) 文字は、文字クラスの最初または最後に表示する必要があります。そうしないと、範囲が指定されてしまいます! (@ JoshuaCheekに感謝します。)