user3120023
user3120023

Reputation: 307

How to split string at operators

Im creating a calculator in Java.

If i have the user enter a string such as:

7+4-(18/3)/2

So far i have had to have the user enter a space between each number or operator. How would i create an array from the given string where the string is split at either number or an operator so in this case the array would be:

[7, +, 4, -, (, 18, /, 3, ), /, 2]

(The array is of type String)

Any help would be really appreciated

Thanks :)

Upvotes: 2

Views: 3174

Answers (4)

Rohit Jain
Rohit Jain

Reputation: 213311

You haven't specified what you want to do with the array. If you really want to evaluate the expression, then there are already libraries available for that. You can use one of them. But if you only want an array like the one you have shown, then also I wouldn't suggest to use regex. You can write your own parser method like below:

public static String[] parseExpression(String str) {
    List<String> list = new ArrayList<String>();
    StringBuilder currentDigits = new StringBuilder();

    for (char ch: str.toCharArray()) {
        if (Character.isDigit(ch)) {
            currentDigits.append(ch);
        } else {
            if (currentDigits.length() > 0) {
                list.add(currentDigits.toString());
                currentDigits = new StringBuilder();
            }
            list.add(String.valueOf(ch));
        }
    }

    if (currentDigits.length() > 0)
        list.add(currentDigits.toString());

    return list.toArray(new String[list.size()]);
}

Now call it like:

String str = "7+4-(18/3)/2";
System.out.println(Arrays.toString(parseExpression(str)));

and you will get your result.

Upvotes: 1

Martijn Courteaux
Martijn Courteaux

Reputation: 68887

My first attempt was to use "\b", but that didn't split -(. After some searching, I came up with this:

(?<=[\(\)\+\-*\/\^A-Za-z])|(?=[\(\)\+\-*\/\^A-Za-z])

So, you will have to escape it and use it like this:

String input = ...;
String temp[] = input.split("(?<=[\\(\\)\\+\\-*\\/\\^A-Za-z])|(?=[\\(\\)\\+\\-*\\/\\^A-Za-z])");
System.out.println(Arrays.toString(temp));

Input:

7+4-(18/3)/2a^222+1ab

Output:

[7, +, 4, -, (, 18, /, 3, ), /, 2, a, ^, 222, +, 1, a, b]

See it in action here:
http://rubular.com/r/uHAObPwaln
http://ideone.com/GLFmo4

Upvotes: 1

Tim B
Tim B

Reputation: 41208

The way I would do this is just scan the string myself to be honest. You will want to build an operation from the results anyway so you don't really gain anything by using an automated parser/splitter/etc.

Here is a rough sketch of the code:

List<Operations> ops = new ArrayList();

for (int i=0;i<str.length();i++) {

   char c = str.get(i);
   if (c == '.' || c >= '0' || c<='9') {
       // extract a number, moving i onwards as I do 
       // insert number into ops (new Operation(num))
   } else if (c!= ' ') {
       Operator operator = operators.get(c);
       if (operator == null) {
           // Handle invalid input - could just skip it
       } else {
           // Add operator to ops
       }
   }
}

You would need to define operators for each of the various symbols.

Once you have done that you have parsed the string out to hold only the important data and compiled a list of what operations they are.

Now you need to work out how to process that list of operations applying correct precedence rules etc :) The simplest way may just be to repeatedly loop through the list each time performing each calculation that is valid that time around.

i.e.

1+2*(3+4)-(4+2)

First pass:

1+2*12-6

Second pass:

1+24-6

Result:

19

Upvotes: 1

Zaheer Ahmed
Zaheer Ahmed

Reputation: 28578

try this:

String[] temp = expression.split("[\s+-\\\(\)]+");

will split on:

  • white spaces
  • + operator
  • - operator
  • \ character
  • ( character
  • ) character

Upvotes: 4

Related Questions