Разделение простого математического выражения с помощью регулярного выражения - PullRequest
2 голосов
/ 30 июля 2010

Я пытаюсь разбить регулярное выражение на уравнения типа 1.5 + 4.2 * (5 + 2) с операторами - + * /, поэтому выходные данные будут вводиться в массив, чтобы я мог анализировать индивидуально

[0]1.5
[1]+
[2]4.2
[3]*
[4](
[5]5
[6]+
[7]2
[8]) 

Я обнаружил, что \b будет работать на 1+2+3, однако, если бы у меня были десятичные точки, он не разбился бы.

Я попытался разбить на \b(\.\d{1,2}), но он не разбивает на десятичную точку

Ответы [ 4 ]

16 голосов
/ 31 июля 2010

В качестве альтернативы можно использовать комбинацию lookahead и lookbehind для сопоставления нулевой ширины.

    String equation = "1.5+4.2*(5+2)";

    String regex = "(?<=op)|(?=op)".replace("op", "[-+*/()]");

    // actual regex becomes (?<=[-+*/()])|(?=[-+*/()])

    System.out.println(java.util.Arrays.toString(
        equation.split(regex)
    ));
    //  ___  _  ___  _  _  _  _  _  _
    // [1.5, +, 4.2, *, (, 5, +, 2, )]

Объяснение

  • […] - определение класса символов
  • (?<=…) - взгляд назад;он утверждает, что мы можем сопоставить слева
  • (?=…) - это взгляд в будущее;он утверждает, что мы можем сопоставить вправо
  • this|that является чередованием
  • Таким образом, (?<=op)|(?=op) совпадает везде после или до op
    • ..где op заменено на [-+*/()], т. е. класс символов, соответствующий операторам
      • Обратите внимание, что - здесь первый, поэтому он не становится метасимволом определения диапазона

Ссылки

Смежные вопросы


Дополнительные примеры регулярных выражений с нулевой шириной для разделения

Вот еще несколько примеров разбиения на конструкции соответствия нулевой ширины;это может быть использовано для разделения строки, но также для сохранения разделителей.

Простое разделение предложений с сохранением знаков препинания:

    String str = "Really?Wow!This.Is.Awesome!";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=[.!?])")
    )); // prints "[Really?, Wow!, This., Is., Awesome!]"

Разделение длинной строки на части фиксированной длины с использованием \G

    String str = "012345678901234567890";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=\\G.{4})")
    )); // prints "[0123, 4567, 8901, 2345, 6789, 0]"

Разделить перед заглавными буквами (кроме первой!)

    System.out.println(java.util.Arrays.toString(
        "OhMyGod".split("(?=(?!^)[A-Z])")
    )); // prints "[Oh, My, God]"

В соответствующих вопросах ниже приведены различные примеры.

Связанные вопросы

4 голосов
/ 30 июля 2010
Pattern pattern = Pattern.compile("((\\d*\\.\\d+)|(\\d+)|([\\+\\-\\*/\\(\\)]))");
Matcher m = pattern.matcher("1.5+4.2*(5+2)/10-4");
while(m.find()) {
    System.out.printf("%s ", m.group());
}

output: 1.5 + 4.2 * ( 5 + 2 ) / 10 - 4

Вы также можете использовать?: Чтобы избежать захвата групп.Я оставил это, чтобы сделать это простым.

3 голосов
/ 30 июля 2010

Использовать совпадение вместо разделения:

(?:\d+\.)?\d*(?:e[+\-]?\d+)?|[\s\-\/()+*%=]

Это регулярное выражение также будет принимать действительные числа с плавающей точкой, такие как: 1.2e+3 * 2, которое должно быть равно 2400. регулярные выражения, приведенные другими респондентами, потерпят неудачу.

1 голос
/ 30 июля 2010

Разбить строку, используя [+-/*()].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...