簡體   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