#java #regex #split
#java #регулярное выражение #разделение
Вопрос:
Как я могу разделить строку следующим образом
"-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
Комментарии:
1. @KennyTM 4,-,3 но если бы это было «4—3», то 4,-,-3
Ответ №1:
Использовать regex для этой задачи непрактично: вам лучше создать какой-нибудь токенизатор / лексер для создания токенов из вашего источника ввода. Особенно это затрудняет разделение регулярных выражений из-за унарных знаков минус.
Но чтобы ответить на ваш вопрос, вы могли бы разделить по следующему шаблону:
(?=[ */()^])|(?<=[ */()^])|(?<=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
Ответ №2:
Я предполагаю, что вы в конечном итоге хотите оценить это выражение. Вот код, который вычисляет арифметические выражения. Он поддерживает базовые арифметические операторы над целыми числами круглые скобки. Адаптировать его для поддержки литералов с плавающей запятой должно быть довольно легко.
public class CompactSolver {
private String input;
public CompactSolver(String input_) {
input = input_.trim();
}
private char peek(int offset) {
return offset >= input.length() ? '' :
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 resu<
}
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 resu<
}
return literal();
}
private double literal() {
for (int i = 0; true; i)
if (!Character.isDigit(peek(i)))
return Integer.parseInt(consume(i));
}
}