2017-02-09 33 views
3

Я пытаюсь разбить строку арифметического уравнения на токены в Java. Эти уравнения также включают символы неравенства! =, < =,> =,> и <.разделение символов неравенства в строке на токены? (Java/Regex)

например. (2 * 2 < = 5) должна быть разделена как:

(, 2, *, 2, < =, 5, )

Прямо сейчас, мое решение добавляет пробел перед & после каждого оператора, затем разбивая его на пробелы, но у меня возникают проблемы с дифференциацией < = и <, когда я это делаю. Я полагаю, вам понадобится регулярное выражение, которое проверяет, нет ли = после < или нет, но я не могу заставить его придумать тот, который работает.

Как бы я это сделал? Или есть лучший способ?

Что я могу сделать прямо сейчас:

String[] tokens = expression 
      .replaceAll("\\+", " + ") 
      .replaceAll("\\^", "^") 
      .replaceAll("^-", "-1*") 
      .replaceAll("-\\(", "-1*(") 
      .replaceAll("-", " -") 
      .replaceAll("\\*", " * ") 
      .replaceAll("/", "/") 
      .replaceAll("!", " !") 
      .replaceAll(">", " >") 
      .replaceAll("<", " <") 
      .replaceAll("\\(", "(") 
      .replaceAll("\\)", ")") 
      .split(" "); 
+0

** Я думаю, вам нужно регулярное выражение, которое проверяет, есть ли no = после <или нет. ** Вы не могли этого сделать. Вы также можете просто проверить '<=' перед '<', и он разрешится сам. В зависимости от требований к производительности это также будет очень медленным решением. 'StringUtils.replaceEach' из Apache StringUtils может быть быстрее. –

+0

Использование должно использовать регулярное выражение для поиска \ d (<=) \ d, а затем заменить захваченную группу на "<=". Другой должен быть \ d (<) \ d. – Sedrick

ответ

1

Я хотел бы сделать это с StringTokenizer. Выход

[(, 2,0, *, 2.0, <, = 5,0,)]

был произведен следующий код:

StreamTokenizer tokenizer = new StreamTokenizer(new StringReader("(2*2<=5)")); 
    List<String> expression = new ArrayList<>(); 
    try { 
     while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) { 
      switch(tokenizer.ttype) { 
       case StreamTokenizer.TT_NUMBER: 
        expression.add(String.valueOf(tokenizer.nval)); 
        break; 
       case StreamTokenizer.TT_WORD: 
        expression.add(tokenizer.sval); 
        break; 
       default: // operator 
        expression.add(String.valueOf((char) tokenizer.ttype)); 
      } 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    System.out.println(Arrays.toString(expression.toArray())); 

Если вам нужна дополнительная информация , взгляните на Java-API http://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html

1

Проверьте, подходит ли вам следующее решение.

Здесь я предположить, что вход является арифметическое уравнение (не любая другая строка) и содержит только целые числа т.е. 2, а не десятичные т.е. 2.0.

private static void method(String str){ 
    Pattern pattern1 = Pattern.compile("[^\\d]+"); 
    Pattern pattern2 = Pattern.compile("[\\d]+"); 
    Matcher matcher1 = pattern1.matcher(str); 
    Matcher matcher2 = pattern2.matcher(str); 
    List<String> list = new ArrayList<String>(); 
    while(matcher1.find()){ 
     list.add(matcher1.group(0)); 
     if(matcher2.find()){ 
      list.add(matcher2.group(0)); 
     } 
    } 
    System.out.println("Token list is::"); 
    for(String st:list){ 
     System.out.print(st+","); 
    } 
} 

Если я пройти (2 * 2 < = 5) с описанным выше способом, он будет выводить следующее.

Токен список ::

(, 2, *, 2, < =, 5),

+0

Спасибо! Могу ли я получить объяснение, что происходит в коде? Из того, что я понимаю, первый образец собирает все числа, в то время как второй паттерн собирает все остальное, верно ли это? – Dylan

+0

Да, ** pattern1 ** для всех нечисловых символов, а ** pattern2 ** - для всех числовых символов. Используя цикл, прошедшая строка проверяется на эти шаблоны, и когда совпадение найдено, оно сохраняется в списке. Поэтому в конце цикла список содержит все маркеры вашего уравнения. – RLD

+0

@Dylan, Если вы удовлетворены моим объяснением, пожалуйста, примите этот ответ, нажав галочку в верхнем левом углу. – RLD