3

I've recently playing around with string manipulation to try to make a calculator that takes only one string and returns an answer. I know I could simply use loadstring to do this, but I am trying to learn more about string manipulation. This is what I have so far: Is there any way I can make it more efficient?

function calculate(exp)
    local x, op, y =
    string.match(exp, "^%d"),
    string.match(exp, " %D"),
    string.match(exp, " %d$")
    x, y = tonumber(x), tonumber(y)       
    op = op:sub(string.len(op))
    if (op == "+") then
        return x + y
    elseif (op == "-") then
        return x - y
    elseif (op == "*") then
        return x * y
    elseif (op == "/") then
        return x / y
    else
        return 0
    end
end

print(calculate("5 + 5"))
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
user3314993
  • 287
  • 1
  • 4
  • 11

1 Answers1

4

You can use captures in the matching pattern to reduce the number of calls to string.match().

local x, op, y = string.match(exp, "^(%d) (%D) (%d)$")

This also eliminates the need to trim the op result.

The conversion tonumber() does not need to be called for x and y. These will automatically be converted when used with the numeric operators.

gwell
  • 2,695
  • 20
  • 20
  • 2
    A pattern that allows liberal and optional whitespace and longer numbers is `"(%d+)%s*(%S+)%s*(%d+)"`. – lhf Mar 20 '14 at 03:14