Java Split Regex - PullRequest
       4

Java Split Regex

1 голос
/ 07 мая 2011

Как я могу разбить строку как

"-3.0*6.7+(5/2)*-0.8--12.98+4^-0.5"

с помощью выражения регулярного выражения в

-3.0,*,6.7,+,(,5,/,2,),*,-0.8,-,-12.98,+,4,^,-0.5

Ответы [ 2 ]

2 голосов
/ 07 мая 2011

Невозможно использовать регулярные выражения для этой задачи: вам лучше создать какой-нибудь токенизатор / лексер для создания токенов из вашего входного источника.Особенно унарные знаки минуса затрудняют разделение регулярных выражений.

Но чтобы ответить на ваш вопрос, вы можете разделить следующий шаблон:

(?=[+*/()^])|(?<=[+*/()^])|(?<=\d-)|(?<=\d)(?=-)

, что означает:

                # Split on:
(?=[+*/()^])    #   the empty space that has one of: +, *, /, (, ), ^ ahead of it
|               #   OR
(?<=[+*/()^])   #   the empty space that has one of: +, *, /, (, ), ^ before it 
|               #   OR
(?<=\d-)        #   the empty space that has a digit followed by a minus sign before it
|               #   OR
(?<=\d)(?=-)    #   the empty space that has a digit before it and a minus sign ahead of it
0 голосов
/ 07 мая 2011

Я предполагаю, что вы в конечном итоге хотите оценить это выражение. Вот код, который оценивает арифметические выражения. Он поддерживает основные арифметические операторы над целыми числами + круглые скобки. Его должно быть достаточно легко адаптировать для поддержки литералов с плавающей запятой.

public class CompactSolver {
  private String input;

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

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

  private boolean consumeIf(char c) {
   if (peek(0) != c)
     return false;
   consume(1);
   return true;
  }

  private String consume(int numChars) {
   if (numChars == 0)
     throw new RuntimeException("syntax error");
   String result = input.substring(0, numChars);
   input = input.substring(numChars).trim();
   return result;
  }

  public double eval() {
   double lhs = mul();
   if (consumeIf('+'))
     return lhs + eval();
   else if (consumeIf('-'))
     return lhs - eval();
   return lhs;
  }

  private double mul() {
   double lhs = unary();
   if (consumeIf('*'))
     return lhs * mul();
   else if (consumeIf('/'))
     return lhs / mul();
   return lhs;
  }

  private double unary() {
   if (consumeIf('-'))
     return -unary();

   if (consumeIf('(')) {
     double result = eval();
     if (!consumeIf(')'))
       throw new RuntimeException("Missing ')'");
     return result;
   }

   return literal();
  }

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