По прошествии некоторого времени работы с этой проблемой мне трудно понять синтаксис Regex именно для того, что мне нужно.
В курсе Java, который я беру, нам поручено построить калькулятор, способный принимать строку выражения (написанную с круглыми скобками или без нее) и правильно ее оценивая.
Концепция синтаксического анализа выражения состоит в том, что у вас есть строка...
5+16/20-56+7-20*16/9
И вы хотите получить два ArrayLists через "split":
{5,16,20,56,7,20,16,9}
{+,/,-,+,-,*,/}
Затем вы выполняете операции по частям в порядке приоритета операции, освобождая операции из вашего массива ArrayList, пока ваш массив чисел не будет иметь один элемент: конечный результат.
К сожалению, у меня нет опыта работы с Regex
и я не могу понять смысл учебников и примеров, которые я читаю.
Я не могу понять, как разбить на основе "[*-/+]"
, и я не могу понять, как выбрать целые числа для разделения, а не просто цифры. Из-за этих ошибок я не могу скомпилировать свой код. Один рабочий фрагмент кода, который я получил:
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Tester
{
public static void main(String[] args)
{
String expression = "3+5+6-10*20/150-14+76%2";
// String[] operands = expression.split("");
String[] operators = expression.split("[0-9]");
// System.out.println(operands);
System.out.println(operators);
}
}
приводит к
[Ljava.lang.String;@308ab721
И я понятия не имею, откуда это взялось.
Может ли кто-нибудь помочь мне выяснить, что я делаю неправильно? Или указать на очень хороший уроки для начинающих в Regex?
Я ценю вашу помощь, все.
operands
и operators
- это array
для печати array
вы можете сделать
System.out.println(Arrays.toString(operands));
System.out.println(Arrays.toString(operators));
И вы должны разбить его так:
String[] operands = expression.split("[\\+\\-\\*\\%\\/]");
String[] operators = expression.split("[0-9]+");
Вы печатаете адрес памяти ваших переменных. Если вам требуется строковое представление, вы можете сделать
System.out.println(Arrays.toString(operators));
То, что происходит за кулисами, - это метод println()
вызывающий toString()
для любого объекта, который передается ему. По умолчанию реализация toString()
для массива в Java - это возврат адреса памяти, поэтому вы получаете эту уродливую вещь.
Я не эксперт, но это должно сработать для вас:
public static void main(String[] args)
{
String expression = "3+5+6-10*20/150-14+76%2";
String[] operands = expression.split("[-+*%/]");
String[] operators = expression.split("[0-9]+");
System.out.println(Arrays.toString(operands));
System.out.println(Arrays.toString(operators));
}
Вам нужно избежать метасимволов Regex (или в этом случае просто изменить порядок) и правильно напечатать ваши массивы.
Небольшая разработка:
В Regex некоторые символы имеют особое значение. Вы уже использовали их, указав диапазон 0-9
, при этом тире является метасимволом. То же самое относится к -
. Вы можете увидеть полный список здесь.
Я фактически использовал метасимвол +
(который "соответствует предыдущему подвыражению один или несколько раз") в шаблоне с измененным номером, чтобы уменьшить количество пустых строк, которые были разделены. Он делает это путем сопоставления одного или нескольких вхождений цифры.
[]
. В частности, +
и *
имеют специального значения в квадратных скобках. (2) Если бы вы избежали их, вы сделали бы это с обратной косой чертой, а не с прямой. Все, что вы здесь сделали, - это пять раз добавили косую черту в свой класс персонажа, что безвредно, но выглядит глупо.
Если это просто цифры или не номера, регулярное выражение просто:
String[] operands = expression.split("\\D+");
String[] operators = expression.replaceAll("^\\d+", "").split("\\d+");
Значения регулярных выражений:
\D+
1 или более цифр (см. Демонстрацию)\D+
1 или более цифр (см. Демонстрацию) Вызов replaceAll()
обрезает ведущие цифры из выражения, поэтому вы не получите пустым, как первый оператор.
replaceAll()
например