[英]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.