Regexp问题涉及反向抛光计算器

use*_*016 2 ruby regex rpn calculator

我正在尝试使用正则表达式来解决反向抛光计算器问题,但我遇到了将数学表达式转换为常规形式的问题.

我写:

puts '35 29 1 - 5 + *'.gsub(/(\d*) (\d*) (\W)/, '(\1\3\2)')
Run Code Online (Sandbox Code Playgroud)

打印:

35 (29-1)(+5) *
Run Code Online (Sandbox Code Playgroud)

预期

(35*((29-1)+5)) 
Run Code Online (Sandbox Code Playgroud)

但我得到了不同的结果.我究竟做错了什么?

And*_*ong 5

我假设你的意思是你尝试过

puts '35 29 1 - 5 + *'.gsub(/(\d*) (\d*) (\W)/, '(\1\3\2)')
                    ^           ^
Run Code Online (Sandbox Code Playgroud)

无论如何,你必须使用量词+而不是*,否则你将匹配一个空字符串\d*作为你的一个捕获,因此(+5):

/(\d+) (\d+) (\W)/
Run Code Online (Sandbox Code Playgroud)

我会进一步扩展/约束表达式,如:

/([\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)".
Run Code Online (Sandbox Code Playgroud)

...而不是使用gsub,sub在一个while循环中使用,当它检测到不能再进行替换时退出.这非常重要,否则您将违反操作顺序.例如,看看这个Rubular演示.您可以看到,通过使用gsub,您可能会替换第二个三元组原子,"5 +*",当真正的第二个迭代应该替换第一个三元组替换"早期"三元组!

警告:-(减号)字符必须出现第一个最后一个字符类,因为否则会指定一个范围!(感谢@JoshuaCheek.)

  • 真棒的答案!但减号也可以先出现. (2认同)