找不到适合这种数学表达式的模式:2*-5+ sin(1.5*4)+(28- 3^4-(cos(3+(19*3)+1+(6/2))/2+tan(1+cos(1+9))-6/3+2.3*3.3345)+1)+1)-(4/2)
其中cos内部有(或不是)内部括号。
理想的结果是:
1. cos(3+(19*3)+1+(6/2))
2. cos(1+9)
我尝试cos\(.+?\)
,但我只获得了cos(3 + (19*3)
。如果我正在尝试一个贪婪的量词,我会得到整个字符串,直到最后)
提前谢谢你!
答案 0 :(得分:1)
我建议接受要解析的字符串的方法,在起始平衡符号之前的字符串,字符分隔符以及包含或排除分隔符(标记)的标记。
请参阅Java IDEONE demo:
public static List<String> getBalancedStr(String s, String strBefore, Character markStart,
Character markEnd, Boolean includeMarkers) {
Matcher m = Pattern.compile("(?=(\\b\\Q" + strBefore + markStart.toString() + "\\E.*))").matcher(s);
List<String> subTreeList = new ArrayList<String>();
while (m.find()) {
int level = 0;
int lastOpenBracket = -1;
for (int i = 0; i < m.group(1).length(); i++) {
char c = m.group(1).charAt(i);
if (c == markStart) {
level++;
if (level == 1) {
lastOpenBracket = (includeMarkers ? i : i + 1);
}
}
else if (c == markEnd) {
if (level == 1) {
if (includeMarkers) {
subTreeList.add(strBefore + m.group(1).substring(lastOpenBracket, i + 1));
} else {
subTreeList.add(m.group(1).substring(lastOpenBracket, i));
}
break;
}
level--;
}
}
}
return subTreeList;
}
样本用法:
String s = "2*-5+ sin(1.5*4)+(28- 3^4-(cos(3+(19*3)+1+(6/2))/2+tan(1+cos(1+9))-6/3+2.3*3.3345)+1)+1)-(4/2)";
System.out.println("cos: " + getBalancedStr(s, "cos", '(', ')', true));
// cos: [cos(3+(19*3)+1+(6/2)), cos(1+9)]
System.out.println("sin: " + getBalancedStr(s, "sin", '(', ')', true));
// sin: [sin(1.5*4)]
System.out.println("tan: " + getBalancedStr(s, "tan", '(', ')', true));
// tan: [tan(1+cos(1+9))]
请注意,该方法会编译正则表达式 - "(?=(\\b\\Q" + strBefore + markStart.toString() + "\\E.*))"
- 仅匹配cos
或sin
作为整个单词(因为\b
是单词边界)并且.*
将匹配到该行的结尾。如果您想支持多行输入,请使用前面的(?s)
:"(?s)\\b\\Q" + strBefore + markStart.toString() + "\\E.*"
。由于模式位于未锚定的正向前瞻中的捕获组中,我们收集所有重叠匹配,并且在每次匹配时仅获得1个平衡子字符串(因为在我们找到相应的匹配结束分隔符之后,我们突破了{{1循环。