實現一個輕量級表達式解析器,將類似 new(com.pkg.Class).method(arg1,arg2) 的字符串分解為 Token 序列,支持方法調用鏈、字符串字面量、參數列表。
ini:初始狀態,累積標識符。brkStart:遇到 (,輸出當前 Token 並輸出 (。brkEnd:遇到 ),輸出當前 Token 並輸出 )。strStart/strEnd:雙引號包裹的字符串字面量。. 在 brkEnd 後輸出為單獨 Token,支持鏈式調用。, 在 brkStart 內分隔參數。package com.attilax.fsm;
import java.util.List;
import com.google.common.collect.Lists;
public class JavaExpFsm {
List<String> tokens = Lists.newLinkedList();
String curToken = "";
String curStat = "ini";
private String code;
public char[] code_char_arr;
public JavaExpFsm(String code) { this.code = code; }
public static void main(String[] args) {
String code = "new(com.attilax.util.connReduceDync).set_resfile(uc_js.txt).joinNout()".trim();
// code = "new(com.attilax.agent.AgentRechargeService).getSubMemTotalsRecycleByAgentId(\"promoter:$pid$,fld2:v2\")";
List li = new JavaExpFsm(code).getTokens();
for (Object o : li) System.out.println(o);
System.out.println(li);
}
public List getTokens() {
code_char_arr = code.toCharArray();
for (char c : code_char_arr) {
if (c == '(' && !curStat.equals("strStart")) {
curStat = "brkStart";
tokens.add(curToken); tokens.add("(");
curToken = ""; continue;
}
if (c == ')' && !curStat.equals("strStart")) {
curStat = "brkEnd";
if (curToken.length() > 0) tokens.add(curToken);
tokens.add(")"); curToken = ""; continue;
}
if (c == '.' && curStat.equals("brkEnd")) {
tokens.add("."); curToken = ""; continue;
}
if (c == '\"' && curStat.equals("brkStart")) {
curStat = "strStart"; curToken = ""; continue;
}
if (c == '\"' && curStat.equals("strStart")) {
curStat = "strEnd"; tokens.add(curToken); curToken = ""; continue;
}
if (c == ',' && curStat.equals("brkStart")) {
tokens.add(curToken); curToken = ""; continue;
}
curToken += c;
}
return tokens;
}
}
輸入: new(com.attilax.user.AgentService).login(admin,admin) 輸出: [new, (, com.attilax.user.AgentService, ), ., login, (, admin, admin, )]
作者:Attilax Akbar Al Rapanui (艾龍) | 郵箱:1466519819@qq.com | 博客:https://www.cnblogs.com/attilax/