我希望以下字符串由(相对于括号对)最外层运算符(在本例中:'+')分割:
1: "((20 + 20) + a)"
2: "(20 + ((20 + 20) + 20))
结果应该是这样的:
1: "((20 + 20) " and " a)"
2: "(20 " and " ((20 + 20) + 20))"
你不能用正则表达式来做到这一点,但你可以尝试这样的事情:
// locations of top-level operators:
List<Integer> locations = new ArrayList<Integer>();
int level = 0;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c == '(') {
level++;
}
else if (c == ')') {
level--;
}
else if ("+-*/".indexOf(c) >= 0 && level == 1) {
locations.add(i);
}
}
substring()
然后,您可以使用和 中的任何内容“拆分”您的字符串locations
。
如果您总是想在最外层的运算符上进行拆分(例如,在+
in上拆分(((a + 1)))
),那么事情会变得有些棘手,但您的整体方法不必大幅改变。想到的一个想法是构建一个映射到字符串中位置的Map<OperatorData, Integer>
(其中OperatorData
包含操作符标记(例如+
)的类和一个表示嵌套多远的 int 的类)。OperatorData
可以Comparable
基于嵌套级别。
OperatorData
可能看起来像这样:
class OperatorData implements Comparable<OperatorData> {
private String token;
private int level;
// constructor etc.
@Override
public int compareTo(OperatorData other) {
return Integer.compare(level, other.level);
}
}
然后,您可以浏览此映射并在嵌套级别最低的运算符上进行拆分。该方法可能如下所示:
// location of top-level operators:
Map<OperatorData, Integer> operators = new HashMap<>();
int level = 0;
int i = 0;
while (i < str.length()) {
char c = str.charAt(i);
if (c == '(') {
level++;
} else if (c == ')') {
level--;
} else if (isOperatorChar(c)) {
final int index = i;
StringBuilder token = new StringBuilder();
token.append(c);
while (isOperatorChar(c = str.charAt(i + 1))) {
token.append(c);
i++;
}
operators.put(new OperatorData(token.toString(), level), index);
}
i++;
}
// find smallest OperatorData in map