我正在尝试拆分表示为String的算术等式,我想保留多字符分隔符:{==, !=, >=, <=, >, <}
这就是我所拥有的:
String expression = "2*(5 +1)- 3 * 2 >= 6^3.1 + 5";
expression = expression.replaceAll("\\s", "");
String[] parsedExpression = expression.split("((?<===)|(?===))|"
+ "((?<=>=)|(?=>=))|"
+ "((?<=!=)|(?=!=))|"
+ "((?<=<=)|(?=<=))|"
+ "((?<=>)|(?=>))|"
+ "((?<=<)|(?=<))");
然而它会像这样拆分:
[2*(5+1)-3*2, >, =, 6^3.1+5]
当所需的分割是这样的时候:
[2*(5+1)-3*2, >=, 6^3.1+5]
我猜测问题是我的规则是使用>
和<
作为导致问题的分隔符,但我不知道如何修复它。
答案 0 :(得分:1)
向(?!=)
和<
外观添加否定预测>
,以确保=
成为运营商的一部分时不匹配:
String[] parsedExpression = expression.split("((?<===)|(?===)|"
+ "(?<=>=)|(?=>=)|"
+ "(?<=!=)|(?=!=)|"
+ "(?<=<=)|(?=<=)|"
+ "(?<=>(?!=))|(?=>(?!=))|" // See here
+ "(?<=<(?!=))|(?=<(?!=)))"); // and here
请参阅IDEONE demo
System.out.println(Arrays.toString(parsedExpression));
打印[2*(5+1)-3*2, >=, 6^3.1+5]
。
答案 1 :(得分:0)
表达式中只能有一个标记(“&gt;”,“&gt; =”,“==”等)吗?你是否允许“5&lt; 6&lt; 7&lt; 7”这样的东西?
虽然它不使用正则表达式,但您可以尝试这样的事情。
String[] parsedExpression = new String[3]; // assuming form "3 < 4". may need to modify a little
String[] tokens = {"==", "!=", "<", ">", "<=", ">="};
int idxOfToken = expression.indexOf(try every token until one is present);
String comparOp = ""; // set to operator you found
int additional = comparOp.length() == 2 ? 2 : 1;
parsedExpression[0] = expression.substring(0, idxOfToken);
parsedExpression[1] = comparOp;
parsedExpression[2] = expression.substring(idxOfToken + additional);
答案 2 :(得分:0)
因为你在宽度为零的外观上分裂,即使你最初匹配一个两个字符的模式,匹配位置也不会超过整个模式。相反,您可以匹配模式的其他部分。
因此,即使您最初匹配:>=
,其中的=
也会匹配第二次。
虽然可以使用看似分散的方法来解决您的问题,但它却是一个难以理解的正则表达式。采用不同的方法会更好,更简单。
例如,您可以匹配分隔符或非分隔符:
/[^><=]+|[><=]+/
此类模式的所有匹配列表将根据需要拆分字符串。这会对您的输入数据做出某些假设,但如果需要可以轻松调整。例如,它可以扩展为仅匹配有效的分隔符。
查看工作here。
答案 3 :(得分:0)
更新1:第4种模式无法正常工作。
您希望仅在以下内容之前和之后进行拆分:==
,!=
,>=
,<=
,>
,<
, (为清楚起见,例如使用COMMENTS
/ (?x)
):
(?= [=!]= )
:在==
之前,!=
(?= [><] )
:在>
之前,<
(包括>=
,<=
)(?<= [=!><]= )
:==
之后,!=
,>=
,<=
(?<= [><](?!=) )
:>
之后,<
,后面没有=
前两个可以使用|
作为(?= [=!]= | [><] )
进行组合
最后两个可以使用|
作为(?<= [=!><]= | [><](?!=) )
进行组合。
所以,所有组合使用(?= [=!]= | [><] ) | (?<= [=!><]= | [><](?!=) )
使用COMMENTS
标志,或者只是:
(?=[=!]=|[><])|(?<=[=!><]=|[><](?!=))
测试
String regex = "(?=[=!]=|[><])|(?<=[=!><]=|[><](?!=))";
String[] split = "2*(5+1)-3*2 >= 6^3.1+5".split(regex);
System.out.println(Arrays.toString(split));
split = "a == b != c >= d <= e > f < g = h ! i".split(regex);
System.out.println(Arrays.toString(split));
输出
[2*(5+1)-3*2 , >=, 6^3.1+5]
[a , ==, b , !=, c , >=, d , <=, e , >, f , <, g = h ! i]
更新2
要获得完整的答案,我想根据Pushkin
和dan1111
的想法展示一个解决方案,即找到运营商。
模式更简单,更容易理解。可能也表现得更好。
String text = "2*(5+1)-3*2 >= 6^3.1+5";
Matcher m = Pattern.compile("[=!]=|[><]=?").matcher(text);
if (m.find()) {
String left = text.substring(0, m.start());
String oper = m.group(); // or text.substring(m.start(), m.end());
String right = text.substring(m.end());
System.out.printf("[%s, %s, %s]%n", left, oper, right);
}
输出
[2*(5+1)-3*2 , >=, 6^3.1+5]