Java regex: How to replace all character inside a

2019-08-22 07:29发布

问题:

How do I able to replace:

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

with

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

with regex?

Thanks, J

回答1:

this doesn't really look like a very good job for a regex. It looks like you might want to write a quick recursive descent parser instead. If I understand you correctly, you want to replace the infix operator % with a function name XYZ?

So (expression % expression) becomes XYZ(expression, expression)

This looks like a good resource to study: http://www.cs.uky.edu/~lewis/essays/compilers/rec-des.html



回答2:

I don't know much about regex, but try looking at this, especially 9 and 10: http://www.mkyong.com/regular-expressions/10-java-regular-expression-examples-you-should-know/

And of course: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html

You could at least check them out until an in depth answer comes along.



回答3:

See this code:

    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);

The output is as you expect it:

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

However keep in mind that it is a bit hacky and it might not work exactly as you expect it. Btw, I had to change a bit the output I added couple of brackets: XYZ((90+1), ( 100-4/(6-4 ) )) because otherwise you were not following your own conventions. Hopefully this code helps you. For me it was a good exercise at least.



回答4:

Would it satisfy your requirements to do the following:

  1. Find ( at first position or preceded by space and replace it with XYZ(
  2. Find % and replace it with ,

If those two instructions are sufficient and satisfactory, then you could transform the original string in three "moves":

  1. Replace ^\( with XYZ(
  2. Replace \( with XYZ(
  3. Replace % with ,