7

I need to split an expression like

a+b-c*d/e 

and get a, b, c, d, e seperately(as array of strings) as well as =,-,*,d,/(also an array of operators) separately. I have tried like:

String myString;

String myString={"a+b-c*d/e");

String[] result=new String();

String[] separator=new String[]{"+","-","/","*"};

result=myString.split(separator);

But, it shows an error. How to solve it?

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
Sandesh Sharma
  • 1,064
  • 5
  • 16
  • 32

5 Answers5

23

1st problem: -

Multiple declaration of String myString;

2nd problem: -

String initialized incorrectly. Double quotes missing at the ends. Remove bracket and brace from the ends.

String myString = "a+b-c*d/e";

3rd problem: -

String array initialized with an String object, rather than an array object.

String[] result=new String();  // Should be `new String[size]`

In fact, you don't need to initialize your array before hand.

4th problem: -

String.split takes a Regular Expression as argument, you have passed an array. Will not work.

Use: -

String[] result = myString.split("[-+*/]");

to split on all the operators.


And regarding your this statement: -

as well as =, -, *, d, / (also an array of operators) separately.

I don't understand what you want here. Your sample string does not contains =. And d is not an operator. Please see if you want to edit it.

UPDATE : -

If you mean to keep the operators as well in your array, you can use this regex: -

String myString= "a+b-c*d/e";
String[] result = myString.split("(?<=[-+*/])|(?=[-+*/])");
System.out.println(Arrays.toString(result));

/*** Just to see, what the two parts in the above regex print separately ***/
System.out.println(Arrays.toString(myString.split("(?<=[-+*/])")));
System.out.println(Arrays.toString(myString.split("(?=[-+*/])")));

OUTPUT : -

[a, +, b, -, c, *, d, /, e]
[a+, b-, c*, d/, e]
[a, +b, -c, *d, /e]

(?<=...) means look-behind assertion, and (?=...) means look-ahead assertion.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • I agree with you on all points, however, the `split` will not keep the operators, which is something which the OP seems to be after. – npinti Nov 23 '12 at 08:05
  • @npinti.. Yeah that part I don't understand what OP wants. Because he have included `d` in his operator. – Rohit Jain Nov 23 '12 at 08:10
  • @npinti.. Added Regex for that too. – Rohit Jain Nov 23 '12 at 08:15
  • 1
    for the 1st kind of output you can also split using word boundary like `myString.split("\\b")`. – Master Chief Oct 09 '19 at 04:41
  • I have used the updated expression and intend to use only for integers and double numbers, parse those numbers and solve the expression. How can we have `-b` in the list if expression is `a+-b`. This signed behavior is only expected for negative numbers, how do I get that? – Vaishnav Mhetre Oct 20 '19 at 10:38
4

Besides the split approach, you could also use java.util.StringTokenizer:

 String myString = "a+b-c*d/e";

 List<String> operatorList = new ArrayList<String>();
 List<String> operandList = new ArrayList<String>();
 StringTokenizer st = new StringTokenizer(myString, "+-*/", true);
 while (st.hasMoreTokens()) {
    String token = st.nextToken();

    if ("+-/*".contains(token)) {
       operatorList.add(token);
    } else {
       operandList.add(token);
    }
 }

 System.out.println("Operators:" + operatorList);
 System.out.println("Operands:" + operandList);

Result:

Operators:[+, -, *, /]
Operands:[a, b, c, d, e]
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
1

Just to get the a/b/c/d/e:

String myString = "a+b-c*d/e";
String[] result=myString.split("[-+*/]");

In a more readable form:

String myString = "a+b-c*d/e";
String[] result2=myString.split("["+Pattern.quote("+-*/")+"]");

To get the +-*/:

ArrayList<Character> list = new ArrayList<Character>();
for (char c:myString.toCharArray())
{
   if ("+-*/".contains(""+c)) list.add(c);
}
System.out.println(list);

Edit: removed unneeded escape characters.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
  • 2
    You don't need to escape `+`, `*` inside character class. – Rohit Jain Nov 23 '12 at 08:10
  • You do need to escape the `*`. – Bernhard Barker Nov 23 '12 at 08:17
  • I'd suggest Andreas' solution above mine. – Bernhard Barker Nov 23 '12 at 08:19
  • 1
    @Dukeling.. No you don't. `*` has special meaning only outside a character class. Try it out without escaping. And move your `-` to the beginning. Else it means `from + to */` – Rohit Jain Nov 23 '12 at 08:19
  • Without escaping it (with \\\\\) I get `Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal character range near index 3` – Bernhard Barker Nov 23 '12 at 08:21
  • 1
    @Dukeling.. Yeah because you have used `-` in between them. Move it either to the beginning or to the end. – Rohit Jain Nov 23 '12 at 08:23
  • I tend to prefer just escaping everything, much less chance of running into unexpected behaviour. Using `quote` is obvious much safer if you're not 100% sure what needs to be escaped. – Bernhard Barker Nov 23 '12 at 08:42
  • @Dukeling.. Using `Pattern.quote` inside a character class is an overkill. No character except `-` has any special meaning in a character class, and hence don't need to be escaped. – Rohit Jain Nov 23 '12 at 08:46
  • @Dukeling.. And even `-` has special meaning when it is not used at the ends. It denotes the `range` if used between two characters. – Rohit Jain Nov 23 '12 at 08:46
1

I think what you want to do, is more like a parser, rather than a tokenizer.

With a string tokenizer, you usually have a long string (i.e. "parameter1;parameter2;parameter3") with several elements concatenated, and using a "token" to separate these elements. With function "String.split", you are basically saying: "Ok, give all elements from this string, but taking into account that character ';' separates different elements". And then you get "parameter1", "parameter2", "parameter3". You do not care about separators.

But in a mathematical expression like yours: "a+b-c*d/e", you want to get all the individual elements (operands and operators). Here there are no explicit separators, and the order is also important for you. I would use a parser library and write a small grammar instead.

0

As far as I know you cannot do what you are after right out of the box. The split(String regex) does not take an entire array (unlike C#), just a string representing a valid regular expression.

What you could do would be to define a Set which contains your operators and 2 ArrayLists. Once you have that, you iterate over your string, check if the set contains that given character (thus determining if it is an operator or not). If it is, then, you put it in one list, if not, you put it in the other.

Finally, you can then use toArray(new String\[arraySize\]) to get back your ArrayLists as String arrays.

npinti
  • 51,780
  • 5
  • 72
  • 96