繁体   English   中英

匹配列表中的字符串并提取值

[英]Match a string from a list and extract values

用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。

我想到的第一个方法当然是一个正则表达式。

但是,将来进行更新或处理对冲案件可能会很复杂。

相反,您可以尝试使用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语言的知识以及性能。

您没有提到表演是一个问题,因此可以根据需要尝试这种方式。

如果您需要比性能更好的性能,则应查看正则表达式。

UPDATE

为了获得更完整的答案,这是带有正则表达式的相同示例:

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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM