我需要拆分包含基本数学表达式的字符串,例如:
"(a+b)*c"
或
" (a - c) / d"
分隔符是+ - * /()和空格,我需要它们作为独立的标记。
基本上结果应该是这样的:
"("
"a"
"+"
"b"
")"
"*"
"c"
对于第二个例子:
" "
"("
"a"
" "
"-"
......
我阅读了很多关于类似问题的问题,这些问题的解决方案不那么复杂,常见的答案是使用零空间正向前瞻和后退。
像这样:(?<=X | ?=X)
X表示分隔符,但是将它们放在这样的类中:
[\\Q+-*()\\E/\\s]
不能以所需的方式工作。
那么我如何格式化分隔符以使分割工作我需要它?
--- ---更新
不应拆分单词类字符和较长的组合
例如“ab”“c1”或“12”
或者简而言之,我需要与StringTokenizer相同的结果,给出参数“ - + * /()”和true。
答案 0 :(得分:1)
如果您将此作为学生工作,这是一回事,但在实践中,这对于词法分析器和解析器来说更像是一项工作。在C中,您将使用lex
和yacc
或GNU flex
和bison
。在Java中,您使用ANTLR
或JavaCC
。
但首先要为您的预期输入编写BNF语法(通常称为输入语言)。
答案 1 :(得分:1)
尝试使用
拆分数据yourString.split("(?<=[\\Q+-*()\\E/\\s])|(?=[\\Q+-*()\\E/\\s])(?<!^)"));
我认为您遇到的问题不在\\Q+-*()\\E
部分,而在(?<=X | ?=X)
&lt; - 它应该是(?<=X)|(?=X)
,因为它应该产生后视和前瞻。
为"_a+(ab-c1__)+12_"
的演示(BTW _
将替换为代码中的空格.SO显示两个空格为一,因此必须使用__
以某种方式呈现它们< /子>
String[] tokens = " a+(ab-c1 )+12 "
.split("(?<=[\\Q+-*()\\E/\\s])|(?=[\\Q+-*()\\E/\\s])(?<!^)");
for (String token : tokens)
System.out.println("\"" + token + "\"");
结果
" "
"a"
"+"
"("
"ab"
"-"
"c1"
" "
" "
")"
"+"
"12"
" "
答案 2 :(得分:0)
请改为尝试:
[-+*()\\s]
为了不代表范围,破折号必须在字符类中排在第一位或最后一位。其余的角色不需要逃避(大概是你试图用\\Q
和\\E
进行的)因为大多数角色无论如何都是在角色类中进行的。
另外,我不知道语法(?<=X|?=X)
。如果它有效,那么很棒。但如果没有,请尝试这种等效扩展,我知道 的语法
(?:(?<=X)|(?=X))
答案 3 :(得分:0)
您可以使用以下正则表达式:
\s*(?<=[()+*/a-z-])\s*
?<=
产生零问题断言,即它们匹配,但不包括组中匹配的表达式。 \s*
将处理尾随空格。
代码示例:
String a = " (a - c) / d * x ";
String regex = "\\s*(?<=[()+*/a-z-])\\s*";
String[] split = a.split(regex);
System.out.println(Arrays.toString(split));
输出:
[ (, a, -, c, ), /, d, *, x]