【发布时间】:2017-08-01 05:11:40
【问题描述】:
我正在尝试拆分 ||、&& 和 () 上的字符串,但无法正确拆分嵌套括号。
示例字符串:
q1 == false || ( q1 == true && q3 != null && ( method(param) - method() ) > 120 )
我当前的正则表达式/代码:
String[] tempTokens = input.split("(?=([|]{2}|[&]{2}|[(]|[)]))|(?<=([|]{2}|[&]{2}|[(]|[)]))");
for (String token : tempTokens) {
if (token.trim().length() > 0) {
System.out.println(token.trim());
}
}
当前输出:
q1 == false
||
(
q1 == true
&&
q3 != null
&&
(
method
(
param
)
- method
(
)
)
> 120
)
想要的输出:
q1 == false
||
(
q1 == true
&&
q3 != null
&&
( method(param) - method() ) > 120
)
基本上,我正在尝试对表达式进行标记,并且仅当它们包含包含>、>=、== 等的完整语句时,我想在括号上拆分。
【问题讨论】:
-
Java 正则表达式引擎不具备匹配平衡文本(嵌套)的能力。所以,它不能匹配像
( method(param) - method() )这样的东西 -
这将是对正则表达式的滥用,你最终会写出一个很长的、可能有问题的表达式。正则表达式用于正则文法。您显示的代码是上下文无关的。查看Regular VS Context-Free Grammars 和Parsing If Statement with Regex
-
如果正则表达式看起来很复杂,那么您可能会在下一次代码重写中丢失它,因为下一个开发人员无法理解逻辑,或者您可能会产生时间复杂度问题(我有看到这种情况发生)。这意味着您应该研究如何简化正则表达式或找到一种不同的方法来标记字符串。在您的情况下,您似乎正在处理语言语法,因此可能需要一个简单的“有限状态机”?
-
我已经在使用 Shunting-Yard 算法将这些表达式解析成一棵树,但问题是我想将每个问题和答案 (
q1 == false) 一起保存在一个节点中,并且是唯一的关系将是&&和||,所以我的算法只有&&和||作为运算符。因此,我正在尝试将字符串拆分为适当的标记以忽略所有其他运算符是否容易。我将尝试修改我的代码以解析所有运算符,看看是否可行。 -
您的要求非常具体。一个简单的正则表达式将不符合它。我认为最好定义一个带有规则的解析器。