在Java中实现以下目标的最有效的方法(CPU时间短)是什么?
让我们说我们有一个字符串列表,如下所示:
1.T.methodA(p1).methodB(p2,p3).methodC(p4)
2.T.methodX.methodY(p5,p6).methodZ()
3 ...
在运行时,我们得到的字符串可能与列表中的字符串之一匹配:
a.T.methodA(p1Value).methodB(p2Value,p3Value).methodC(p4Value) // Matches 1
b.T.methodM().methodL(p10) // No Match
c.T.methodX.methodY(p5Value,p6Value).methodZ() // Matches 2
我想将(a)匹配为(1)并提取p1,p2,p3和p4的值 其中:
p1Value = p1, p2Value = p2, p3Value = p3 and so on.
类似地,对于其他匹配,例如c到2。
答案 0 :(得分:2)
我想到的第一个方法当然是正则表达式。
但是,将来进行更新或处理对冲案件可能会很复杂。
相反,您可以尝试使用 Nashorn 引擎,该引擎允许您在jvm中执行javascript代码。
因此,您只需要创建一个特殊的javascript对象即可处理所有方法:
private static final String jsLib = "var T = {" +
"results: new java.util.HashMap()," +
"methodA: function (p1) {" +
" this.results.put('p1', p1);" +
" return this;" +
"}," +
"methodB: function (p2, p3) {" +
" this.results.put('p2', p2);" +
" this.results.put('p3', p3);" +
" return this;" +
"}," +
"methodC: function (p4) {" +
" this.results.put('p4', p4);" +
" return this.results;" +
"}}";
这是字符串,比第一种情况要好。 您可以将代码编写到js文件中,然后轻松加载该文件。
您在javascript对象中创建了一个特殊属性,即Java HashMap,因此您可以将其作为评估结果,并按名称列出所有值。
因此,您只需评估输入:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
final String inputSctipt = "T.methodA('p1Value').methodB('p2Value','p3Value').methodC('p4Value')";
try {
engine.eval(jsLib);
Map<String, Object> result = (Map<String, Object>)engine.eval(inputSctipt);
System.out.println("Script result:\n" + result.get("p1"));
} catch (ScriptException e) {
e.printStackTrace();
}
您得到了:
脚本结果: p1Value
您可以以相同的方式获取所有其他值。
您需要忽略脚本错误,因为它们应该是未实现的路径。
请记住,每次评估之前都要重置脚本上下文,以避免与先前的值混淆。
与正则表达式相比,此解决方案的优点是易于理解,并在需要时易于更新。
我唯一看到的缺点就是Java语言的知识以及性能。
您没有提及表演是一个问题,因此可以根据需要尝试这种方式。
如果您需要更好的性能,而不是正则表达式。
更新
要获得更完整的答案,下面是带正则表达式的示例:
Pattern p = Pattern.compile("^T\\.methodA\\(['\"]?(.+?)['\"]?\\)\\.methodB\\(['\"]?([^,]+?)['\"]?,['\"]?(.+?)['\"]?\\)\\.methodC\\(['\"]?(.+?)['\"]?\\)$");
Matcher m = p.matcher(inputSctipt);
if (m.find()) {
System.out.println("With regexp:\n" + m.group(1));
}
请注意,此表达式无法处理套期保值情况,对于要解析并获取属性值的每个字符串,您将需要一个reg exp。