我希望以下字符串被(相对于括号对)最外层运算符(在这种情况下:'+')拆分:
1: "((20 + 20) + a)"
2: "(20 + ((20 + 20) + 20))
结果应该是这样的:
1: "((20 + 20) " and " a)"
2: "(20 " and " ((20 + 20) + 20))"
答案 0 :(得分:2)
你不能用正则表达式做到这一点,但你可以尝试这样的事情:
// 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
中的任何内容“拆分”字符串。
如果总是希望拆分最外层的运算符(例如,在+
中的(((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