简体   繁体   English

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

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

What would be the most efficient (low CPU time) way of achieving the following in Java ? 用Java实现以下目标的最有效的方式(CPU时间短)是什么?

Let us say we have a list of strings as follows : 假设我们有一个字符串列表,如下所示:

1.T.methodA(p1).methodB(p2,p3).methodC(p4)
2.T.methodX.methodY(p5,p6).methodZ()
3 ...

At runtime we get strings as follows that may match one of the strings in our list : 在运行时,我们得到如下字符串,它们可能与列表中的字符串之一匹配:

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

I would like to match (a) to (1) and extract the values of p1,p2,p3 and p4 where: 我想将(a)匹配为(1)并提取p1,p2,p3和p4的值,其中:

p1Value = p1, p2Value = p2, p3Value = p3 and so on.

Similarly for the other matches like c to 2 for example. 类似地,对于其他匹配,例如c到2。

The first method I have in mind is of course a regular expression. 我想到的第一个方法当然是一个正则表达式。

But that could be complicated to update in the future or to handle hedge cases. 但是,将来进行更新或处理对冲案件可能会很复杂。

Instead you can try using the Nashorn engine, that allow you to exec javascript code in a jvm. 相反,您可以尝试使用Nashorn引擎,该引擎使您可以在jvm中执行javascript代码。

So you just need to create a special javascript object that handle all your methods: 因此,您只需要创建一个特殊的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;" +
        "}}";

This is a string for semplicity, than handle your first case. 这是简单起见的字符串,而不是处理第一种情况。 You can write the code in a js file and load that one easely. 您可以在js文件中编写代码并轻松加载该文件。

You create a special attribute in your javascript object, that is a Java HashMap, so you get that as the result of the evaluation, with all the values by name. 您在javascript对象中创建了一个特殊属性,即Java HashMap,因此将其作为评估的结果,并按名称列出了所有值。

So you just eval the input: 因此,您只需评估输入:

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

And you got: 你得到了:

Script result: p1Value 脚本结果:p1Value

In the same way you can get all the other values. 以相同的方式,您可以获得所有其他值。

You need to ignore the script errors, are they should be path not implemented. 您需要忽略脚本错误,因为它们应该是未实现的路径。

Just remember to reset the script context before each evaluation, in order to avoid to mix with previous values. 只需记住在每次评估之前重置脚本上下文,以避免与先前的值混淆。

The advantage of this solution compared to regular expressions is that is easy to understand, easy to update when needed. 与正则表达式相比,此解决方案的优点是易于理解,并在需要时易于更新。

The only disadvantage I can see is the knowledge of Javascript, of course, and the performances. 我可以看到的唯一缺点是Java语言的知识以及性能。

You didn't mention the performances as an issue, so you can try this way if is fine for your need. 您没有提到表演是一个问题,因此可以根据需要尝试这种方式。

If you need a better peroformance than you should look on regular expressions. 如果您需要比性能更好的性能,则应查看正则表达式。

UPDATE UPDATE

To have a more complete answer, here is the same example with regular expressions: 为了获得更完整的答案,这是带有正则表达式的相同示例:

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

Please be aware that this expression didn't handle hedge cases, and you're going to need a reg exp for each string you want to parse and grab the attribute values. 请注意,该表达式不能处理套期保值案例,并且您将需要为每个要解析和获取属性值的字符串提供一个reg exp。

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

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