【问题标题】:Java regex: How to replace all character inside a bracket?Java regex:如何替换括号内的所有字符?
【发布时间】:2012-03-18 10:11:31
【问题描述】:

我该如何替换:

((90+1)%(100-4)) + ((90+1)%(100-4/(6-4))) - (var1%(var2%var3(var4-var5)))

XYZ((90+1),(100-4)) + XYZ((90+1),100-4/(6-4)) - XYZ(var1,XYZ(var2,var3(var4-var5)))

使用正则表达式?

谢谢, J

【问题讨论】:

标签: java regex nested recursive-regex


【解决方案1】:

对于正则表达式来说,这看起来并不是一个很好的工作。看起来您可能想要编写一个快速递归下降解析器。如果我理解正确,您想将中缀运算符 % 替换为函数名称 XYZ?

所以(表达式 % 表达式)变为 XYZ(表达式,表达式)

这看起来是一个很好的学习资源:http://www.cs.uky.edu/~lewis/essays/compilers/rec-des.html

【讨论】:

  • 是的。我认为这是一个非常普遍的问题。我几乎放弃在这个特别处理嵌套和递归替换上使用正则表达式。我听说树结构能够做到这一点。您提供的链接可能会有所帮助。我可能需要更多时间将其解释为 Java 代码。对此的任何帮助都非常感谢。谢谢。
【解决方案2】:

我对正则表达式了解不多,但请尝试查看以下内容,尤其是 9 和 10: http://www.mkyong.com/regular-expressions/10-java-regular-expression-examples-you-should-know/

当然还有: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html

您至少可以检查一下,直到出现深入的答案。

【讨论】:

    【解决方案3】:

    查看此代码:

        String input = "((90+1)%(100-4)) + ((90+1)%(100-4/(6-4))) - (var1%(var2%var3(var4-var5)))";
        input = input.replaceAll("%", ",");
        int level = 0;
        List<Integer> targetStack = new ArrayList<Integer>();
        List<Integer> splitIndices = new ArrayList<Integer>();
        // add the index of last character as default checkpoint
        splitIndices.add(input.length());
        for (int i = input.length() - 1; i >= 0; i--) {
            if (input.charAt(i) == ',') {
                targetStack.add(level - 1);
            } else if (input.charAt(i) == ')') {
                level++;
            }
            else if (input.charAt(i) == '(') {
                level--;
                if (!targetStack.isEmpty() && level == targetStack.get(targetStack.size() - 1)) {
                    splitIndices.add(i);
                }
            }
        }
        Collections.reverse(splitIndices); // reversing the indices so that they are in increasing order
        StringBuilder result = new StringBuilder();
        for (int i = 1; i < splitIndices.size(); i++) {
            result.append("XYZ");
            result.append(input.substring(splitIndices.get(i - 1), splitIndices.get(i)));
        }
        System.out.println(result);
    

    输出如你所愿:

    XYZ((90+1),(100-4)) + XYZ((90+1),(100-4/(6-4))) - XYZ(var1,XYZ(var2,var3(var4-var5)))
    

    但是请记住,它有点 hacky,它可能无法完全按照您的预期工作。顺便说一句,我不得不稍微改变一下我添加了几个括号的输出:XYZ((90+1), ( 100-4/(6-4 ) ))因为否则你没有遵循自己的约定。希望这段代码对您有所帮助。至少对我来说,这是一个很好的练习。

    【讨论】:

    • 谢谢鲍里斯。我尝试了一些单元测试,有些失败。就像 (99)%(100) 我可能需要添加 ((99)%(100)) 当我编码那个时间和 XYZ(3+4,XYZ(XYZ(XYZ(XYZ(99,100),88),6 ),5+2)) 编码为 (3+4)%((((((99)%(100))%(88))%(6))%(5+2)) 可能需要更改为为了使用上面的算法解码回 XYZ(3+4,XYZ(XYZ(XYZ(XYZ(99,100),88),6),5+2))。我可能需要调整编码功能,否则它会以不同的方式解码。我尝试添加更多括号,但仍然失败。
    • 是的,抱歉。我的代码中有错误。我要修复它,然后重新发布正确的解决方案
    【解决方案4】:

    执行以下操作是否满足您的要求:

    1. 在第一个位置或前面有空格找到(,并用XYZ(替换它
    2. 找到%并将其替换为,

    如果这两条指令足够且令人满意,那么您可以将原始字符串转换为三个“移动”:

    1. ^\( 替换为XYZ(
    2. \( 替换为XYZ(
    3. % 替换为,

    【讨论】:

      猜你喜欢
      • 2016-07-28
      • 1970-01-01
      • 2013-01-04
      • 2015-10-25
      • 2014-08-14
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多