我如何使用string#split来分隔带分隔符的字符串+ - * /()和空格并将它们保留为额外的标记?

时间:2013-05-17 13:50:48

标签: java regex string parsing

我需要拆分包含基本数学表达式的字符串,例如:
        "(a+b)*c"

        " (a - c) / d"
分隔符是+ - * /()和空格,我需要它们作为独立的标记。 基本上结果应该是这样的:

"("
"a"
"+"
"b"
")"
"*"
"c"

对于第二个例子:

" "
"("
"a"
" "
"-"
......

我阅读了很多关于类似问题的问题,这些问题的解决方案不那么复杂,常见的答案是使用零空间正向前瞻和后退。 像这样:(?<=X | ?=X)
X表示分隔符,但是将它们放在这样的类中:
[\\Q+-*()\\E/\\s]
不能以所需的方式工作。
那么我如何格式化分隔符以使分割工作我需要它?

--- ---更新
不应拆分单词类字符和较长的组合 例如“ab”“c1”或“12” 或者简而言之,我需要与StringTokenizer相同的结果,给出参数“ - + * /()”和true。

4 个答案:

答案 0 :(得分:1)

如果您将此作为学生工作,这是一回事,但在实践中,这对于词法分析器和解析器来说更像是一项工作。在C中,您将使用lexyacc或GNU flexbison。在Java中,您使用ANTLRJavaCC

但首先要为您的预期输入编写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]