How can tokenize this string in java?

How can I break these simple math expressions into separate lines?

I know that I basically want to use the regex:: "[0-9]+|[*+-^()]"but it looks like String.split () will not work, because it also uses delimiter tokens.

I want him to separate all integers: 0-9 and all operators * + - ^ ().

So, 578+223-5^2

It will be divided into:

578  
+  
223  
-  
5  
^  
2  

What is the best way to do this?

+3
source share
9 answers

, , , String , ScriptEngine

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Evaluator {
private ScriptEngineManager sm = new ScriptEngineManager();
private ScriptEngine sEngine = sm.getEngineByName("js");

public double stringEval(String expr)
{
Object res = "";
        try {
           res = sEngine.eval(expr);
          }
         catch(ScriptException se) {
            se.printStackTrace();
        }
        return Double.parseDouble( res.toString());
}

}

:

Evaluator evr = new Evaluator();  
String sTest = "+1+9*(2 * 5)";  
double dd = evr.stringEval(sTest);  
System.out.println(dd); 

, , , , . : a) b) c) , .

+3

, :

String s = "578+223-5^2";
String[] tokens = s.split("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)");

lookaheads and lookbehinds; ( , "" ), , , , .

, . , , , . ( , , Java.)

, , , charAt() substring() Integer.parseInt(). , , .

EDIT:... eval() @Syzygy .

+2

String.split() , , , .

, ...

"578 + 223 - 5 ^ 2 ".split(" ");

...

578
+
223
-
5
^
2
+1

Java-, . , () : 64

  import java.util.ArrayList;
  import java.util.List;

  public class Tokenizer {
     private String input;

     public Tokenizer(String input_) { input = input_.trim(); }

     private char peek(int i) {
        return i >= input.length() ? '\0' : input.charAt(i);
     }

     private String consume(String... arr) {
        for(String s : arr)
           if(input.startsWith(s))
              return consume(s.length());
        return null;
     }

     private String consume(int numChars) {
        String result = input.substring(0, numChars);
        input = input.substring(numChars).trim();
        return result;
     }

     private String literal() {
        for (int i = 0; true; ++i)
           if (!Character.isDigit(peek(i)))
              return consume(i);
     }

     public List<String> tokenize() {
        List<String> res = new ArrayList<String>();
        if(input.isEmpty())
           return res;

        while(true) {
           res.add(literal());
           if(input.isEmpty())
              return res;

           String s = consume("+", "-", "/", "*", "^");
           if(s == null)
              throw new RuntimeException("Syntax error " + input);
           res.add(s);
        }
     }

     public static void main(String[] args) {
        Tokenizer t = new Tokenizer("578+223-5^2");
        System.out.println(t.tokenize());
     }   
  }
+1

-. , (+ and *) , . , .

0

"()" Java, "-"

myString.split("[0-9]+|[\\*\\+\\-^\\(\\)]");

0

You put delimiters only in the split statement. In addition, the middle range -should be shielded.

"578+223-5^2".split("[*+\\-^()]")
0
source

Here is my tokenizer solution that allows negative numbers (unary).

So far, he has been doing everything I need to:

private static List<String> tokenize(String expression)
    {
        char c;
        List<String> tokens = new ArrayList<String>();
        String previousToken = null;
        int i = 0;
        while(i < expression.length())
        {
            c = expression.charAt(i);
            StringBuilder currentToken = new StringBuilder();

            if (c == ' ' || c == '\t') // Matched Whitespace - Skip Whitespace
            {
                i++;
            }
            else if (c == '-' && (previousToken == null || isOperator(previousToken)) && 
                    ((i+1) < expression.length() && Character.isDigit(expression.charAt((i+1))))) // Matched Negative Number - Add token to list
            {
                currentToken.append(expression.charAt(i));
                i++;
                while(i < expression.length() && Character.isDigit(expression.charAt(i)))
                {
                    currentToken.append(expression.charAt(i));
                    i++;
                }   
            }
            else if (Character.isDigit(c)) // Matched Number - Add to token list
            {
                while(i < expression.length() && Character.isDigit(expression.charAt(i)))
                {
                    currentToken.append(expression.charAt(i));
                    i++;
                }
            }
            else if (c == '+' || c == '*' || c == '/' || c == '^' || c == '-') // Matched Operator - Add to token list
            {
                currentToken.append(c);
                i++;
            }
            else // No Match - Invalid Token!
            {
                i++;
            }

            if (currentToken.length() > 0)
            {
                tokens.add(currentToken.toString());    
                previousToken = currentToken.toString();    
            }
        }   
        return tokens;
    }
0
source

Source: https://habr.com/ru/post/1733826/


All Articles