java - cos/sin/tan 的正则表达式,内部带有内括号

标签 java regex

找不到这种数学表达式的合适模式: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)。如果我尝试贪婪量词我得到整个字符串直到最后一个 )

提前谢谢您!

最佳答案

我建议一种接受要解析的字符串、起始平衡符号之前的字符串、字符分隔符以及包含或排除分隔符(标记)的标志的方法。

请参阅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.*))" -仅匹配整个单词的 cossin(因为 \b 是单词边界)和 .* 将匹配到行尾。如果要支持多行输入,请在前面使用 (?s): "(?s)\\b\\Q"+ strBefore + markStart.toString() + "\\E.*"。由于该模式位于未锚定正向前瞻内的捕获组中,因此我们收集所有重叠匹配,并且每次匹配时只会获得 1 个平衡子字符串(因为在找到相应的匹配结束分隔符后,我们就突破了 for 循环。

关于java - cos/sin/tan 的正则表达式,内部带有内括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37235779/

相关文章:

java - Math.cos() 给出错误的结果

java - JVM 启动失败 : java. io.IOException : Cannot run program "/usr/libexec/StartupItemContext; error=2, No such file or directory

regex - Apache重写规则,可以使用或不使用斜杠

c# - 用零填充左边

java - 为什么我们不能覆盖java中的变量

java - Java 中的验证码

java - 每次测试后需要重启JBoss

Javascript:测试在正则表达式字符串中找到单个字符

javascript - 使用单词边界

javascript - 在 JavaScript 中解析格式错误的 JSON