解析包含javascript的字符串

时间:2020-03-09 11:16:50

标签: java regex rhino

我有一个字符串:

2 + 2 = ${2 + 2}
This is a ${"string"}
This is an object: ${JSON.stringify({a: "B"})}
This should be "<something>": ${{
    abc: "def",
    cba: {
        arr: [
            "<something>"
        ]
    }

}.cba.arr[0]}
This should ${"${also work}"}

解析后,我应该得到类似的东西:

2 + 2 = 4
This is a string
This is an object: {"a":"B"}
This should be "<something>": <something>
This should ${also work}

因此,我需要在Java中实现它的帮助,我只需要获取${}之间的内容。

我尝试使用正则表达式:\${(.+?)},但是当其中的字符串包含}

时失败

1 个答案:

答案 0 :(得分:0)

因此,经过一些测试,我得出了以下结论:

ScriptEngine scriptEngine = new ScriptEngineManager(null).getEngineByName("JavaScript");
String str = "2 + 2 = ${2 + 2}\n" +
        "This is a ${\"string\"}\n" +
        "This is an object: ${JSON.stringify({a: \"B\"})}\n" +
        "This should be \"F\": ${var test = {\n" +
        "    a : {\n" +
        "        c : \"F\"\n" +
        "    }\n" +
        "};\n" +
        "test.a.c\n" +
        "}\n" +
        "This should ${\"${also work}\"}"; // String to be parsed
StringBuffer result = new StringBuffer();
boolean dollarSign = false;
int bracketsOpen = 0;
int beginIndex = -1;
int lastEndIndex = 0;
char[] chars = str.toCharArray();
for(int i = 0; i < chars.length; i++) { // i is for index
    char c = chars[i];
    if(dollarSign) {
        if(c == '{') {
            if(beginIndex == -1) {
                beginIndex = i + 1;
            }
            bracketsOpen++;
        } else if(c == '}') {
            if(bracketsOpen > 0) {
                bracketsOpen--;
            }
            if(bracketsOpen <= 0) {
                int endIndex = i;
                String evalResult = ""; // evalResult is the replacement value
                try {
                    evalResult = scriptEngine.eval(str.substring(beginIndex, endIndex)).toString(); // Using script engine as an example; str.substring(beginIndex, endIndex) is used to get string between ${ and }
                } catch (ScriptException e) {
                    e.printStackTrace();
                }
                result.append(str.substring(lastEndIndex, beginIndex - 2));
                result.append(evalResult);
                lastEndIndex = endIndex + 1;
                dollarSign = false;
                beginIndex = -1;
                bracketsOpen = 0;
            }
        } else {
            dollarSign = false;
        }
    } else {
        if(c == '$') {
            dollarSign = true;
        }
    }
}
result.append(str.substring(lastEndIndex));
System.out.println(result.toString());
相关问题