У меня есть калькулятор CLI, и я добавляю функцию квадратного корня.У меня есть это регулярное выражение, которое анализирует входные данные пользователей:
string.scan(/\d*\.?\d+\^?|[-+\/*%()]|sqrt\(\d*\.?\d+\)/)
Он работает с этими входами, как и ожидалось:
calc -o "sqrt(9)" #=> ["sqrt(9)"]
calc -o "sqrt(9) + sqrt(9)" #=> ["sqrt(9)", "+", "sqrt(9)"]
Однако, мое регулярное выражение не учитывает вложенный sqrt.При этом,
calc -0 "sqrt(6+3)"
Я хочу вывод:
["sqrt(6+3)"]
, потому что когда программа находит sqrt
во время поиска, она просто рекурсивно применяет метод scan
с регулярным выражениемпока он не войдет в самую глубокую вложенную формулу и вернется обратно.Но я получаю:
["(", "6", "+", "3", ")"]
Я пытался захватить все, кроме квадратных скобок, но он также захватывает все в других скобках.Так что у меня возникают проблемы с захватом sqrt(9)
и sqrt(6+3)
без единой путаницы с другим.
Любое руководство очень ценится.
ОБНОВЛЕНИЕ: Поэтому, следуя предоставленному ответу, возможно, яМне нужно больше объяснить мою программу, чтобы вы поняли, что происходит.
Скажем, у меня есть ввод 2 * (3 + 5)
, это будет интерпретировано в следующем массиве:
["2", "*", "(", "3", "+", "5", ")"]
Таким образом, программа соответствует PEDMAS, поэтому сначала будет искать круглые скобки, в этой ситуации она их найдет.Основной цикл в основном выглядит следующим образом:
function find_backets
start_i, end_i
for i in array do
if i == "("
start_i = index
find_brackets
end
if i == ")"
end_i = index
# end of nest
end
end
Затем я могу передать свои начальные и конечные местоположения в массиве функции, которая будет выполнять итерацию для каждой вложенной операции.Таким образом, вышеприведенное может интерпретировать это очень хорошо:
calc -o "2 * (6 + (2 * 2))"
#=> ["2", "*", "(", "6", "+", "(", "2", "*", "2", ")", ")"]
Моя идея состоит в том, что, когда он сталкивается с функцией sqrt, он просто просто повторно используетто же самое регулярное выражение, которое используется для ввода данных пользователем, и создайте новый массив и сделайте с ним вышеописанное.Затем, как только это будет сделано, я беру индекс 0 и помещаю его туда, где раньше был sqrt.
РЕДАКТИРОВАТЬ: Так что да, на самом деле не упоминалось, я собираюсь захватить полностью sqrt.Итак, все и вся в чем-то вроде sqrt(5+5*(6/2+sqrt(9))
ОБНОВЛЕНИЕ: Я думаю, что нашел решение
Так что я немного почитал, чтобы узнать, как * + ?
, и это сработало немного больше иЯ думаю (по крайней мере, пока), что это работает
string.scan(/\d*\.?\d+\^?|[-+\/*%()^]|sqrt\(.+?\)+|pi/)
calc -o "sqrt(9)" #=> ["sqrt(9)"]
calc -o "sqrt(3+6)" #=> ["sqrt(3+6)"]
calc -o "sqrt(9) + sqrt(9)" #=> ["sqrt(9)", "+", "sqrt(9)"]
calc -o "sqrt(9) + 2" #=> ["sqrt(9)", "+", "2"]
Обновится немного