我正在尝试使用正则表达式来解决逆波兰计算器问题,但在将数学表达式转换为常规形式时遇到了问题。
我写:
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)')
^ ^
无论如何,您必须使用量词+
而不是*
,否则您将匹配一个空字符串\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)".
...而不是 using gsub
,sub
在一个while
循环中使用,当它检测到无法进行更多替换时退出。这非常重要,否则您将违反操作顺序。例如,看看这个 Rubular 演示。您可以看到,通过使用gsub
,您可能会替换第二个原子三元组“5 + *”,而实际上第二次迭代应该在替换第一个三元组之后替换一个“早期”三元组!
警告:(-
减号)字符必须出现在字符类中的第一个或最后一个,否则它将指定一个范围!(感谢@JoshuaCheek。)