Wyrażenia regularne - parser wyrażeń arytmetycznych

0

Witam,

mam problem z korzystaniem z wyrażeń regularnych. Powiedzmy, że mam łańcuch wczytany z konsolli:
"2+4*5-7" //ale może też być: "2 + 4 *5 -7" czyli dowolna liczba spacji
Pomysł jest taki, żeby rozdzielić ten string na dwie tablice (właściwie listy) stringów w taki sposób:

tab1 = ["2", "4", "5", "7"]
tab2 = ["+", "*", "-"];

Wtedy w klasie Kalkulator można spokojnie zaimplementować metodę do wykonywania działań: z jednej tablicy pobiera operator, z drugiej zmienne (operandy) i zapisuje wynik w pamięci.

Tylko, że nie wiem jak podzielić ten wejściowy string...

Próbowałem czegoś takiego:

Pattern wzorzec = Pattern.compile("([\\+\\*/-])");
		Matcher tekst = wzorzec.matcher(str);

ale nie mogę dostać żadnej grupy rozdzielonego tekstu, a chciałbym dostać same operatory.
Dotąd nie używałem wyrażeń regularnych w żadnym języku więc nie wiem jak to można zrobić. Poza tym zastanawiam się czy istnieje lepsze rozwiązanie na sparsowanie tych wyrażeń.

Z góry dzięki za wszelkie wskazówki

0

moze sprobuj da razy uzyc metody split("wyrazenie regularne") dla tego ciagu znakow, gdzie
pierwsze wywolanie z wyrazeniem \d (to beda nie-cyfry czyli operatory)
drugie wywolanie z wyrazeniem \D (to beda cyfry)

0

a, i te spacje- jak już wysplitujesz to dal każdego elementu tablicy możesz dać .trim() aby usunąć spacje z początku i z końca.

0

Niestety nie działa:

String str = "5 + 3 + 6 * 9 - 4";
Pattern wzorzec = Pattern.compile("[0-9]");
Matcher tekst = wzorzec.matcher(str);
String[] tab = wzorzec.split("[0-9]");
System.out.println(tab.length);
for(int i=0; i<tab.length; i++){
    System.out.println(tab[i]);
}

Wynik:

3
[

]

Wydaje się, że metoda split nie traktuje swojego argumentu wejściowego jako wyrażenia regularnego.

0

String[] tab = STR.split("[0-9]");

pattern i matcher nie jest potrzebne....zajrzyj do dokumentacji klasy String i znajdź metodę split

0

Ok wiem o co chodzi. Problem jest jednak z samym wyrażeniem regularnym, które ma za zadanie parsować operatory. Otóż liczby parsowane są w sposób następujący:

String[] operandy = str.split("[^0-9]");

Jeśli nasz kalkulator działa na liczbach to wszystko jest ok. Ale jeśli będziemy chcieli trochę zwiększyć jego funkcjonalność (np. wprowadzić typ String i wykonywać na nim działania to jest problem. Dlatego wolałbym, aby wyrażeniem regularnym, które rozdzieli operandy od operatorów było coś takiego:

String operandy = str.split("[\\+\\*/-]");

W ten sposób w tablicy operandy będę miał rzeczy, które wpisze użytkownik. Może okazać się, że nie są to liczby, ale sprawdzeniem poprawności zajmie się osobna klasa Walidator. Jeśli chodzi zaś o wyparsowanie operatorów to chciałbym zrobić tak:

String[] operatory = str.split("[^\\+\\*/-]");

Czyli powinny zostać same operatory. Niestety żadne z tych wyrażeń regularnych nie działa i nie wiem jak je poprawić.
Nie chciałbym przeszukiwać tablicy ręcznie, bo skoro język dostarcza odpowiednich narzędzi to trzeba z nich korzystać.

Problemem jest chyba to, że znak "\+" wcale nie oznacza znaku "+" (znaku jako takiego, a nie sekwencji sterującej). Niby w dokumentacji wyczytałem coś takiego:

\cx The control character corresponding to x
ale nie wiem jak wykorzystać tę informację.

Na stronie http://www.regular-expressions.info/characters.html wyczytałem, że wystarczy znak sterujący poprzedzić backslashem, żeby stał się zwykłym znakiem, ale takie coś się nie skompiluje.

Mógłby ktoś podpowiedzieć jak powinny wyglądać wyrażenia regularne, które będą się nadawać do powyższej sytuacji?

0

Nie rozumiem Twojej koncepcji - czy Twój kalkulator ma działać na liczbach w zapisie słownym, tj. np "dziewięć + osiem" ?

Zresztą nieważne:

import java.util.*;

public class Intro {
	public static void main(String[] args) {
		String  str = "5 + 3 + 6 * 9 - 4";
		
		Set<String>set = new HashSet<String>();

		String[]tab = str.split("[^\\+\\*\\-]");
		
		for(String s:tab) {
			if(! s.equals(" "))
				set.add(s.trim());
		}
		System.out.println(set);
	}
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1