Java Shell wildcard tokenizer
-
21-09-2019 - |
题
我Java是极其生锈,而我坚持努力,使用户接口,简化了执行壳脚本或批文件取决于它是Linus或Win32分别。该文件有以下命名约定。
module-verb-object-etc [args-list]
mysql-connect-grid
mysql-connect-rds
mysql-dump-grid
mysql-dump-grid-se314
最后,我想它来分析的明确条款,所以我可以:
- 标记的命令(e。g分隔"-")&缩短他们进入简化的条件对的事情反而觉得自己像统的命令窗口或思科IOS(例如"我的同遗传资源"执行"mysql-连接-格"在unix和*。cmd在win32)
- 并且还在风格的允许的用户要进入缩写的命令,以便他们可以输入一个问题mark(?) 和它将给他们一个提示,唯一剩下的(或下)命令选择(例如"我?"返回mysql&"我?"返回连接,或转储)。Othr返回值将是"含糊"或"未知"的命令,这不是唯一的或不能匹配。它可能看起来微不足道但还有许多数以百计的命令在每个文件夹和我的用户不想想...
我写了一个函数拉的文件列表,从一个目录和retun一系列fileanmes.然后我转换到2维阵列,使用的方法如下返回的一个动态的中小型电网的潜力的命令。
/**********************************************************************************
* MAKE GRID: Parses array of filenames and tokenizes AWS cmds.
* @param strs Array of filenames
**********************************************************************************/
public static String [][] makeGrid(String strs[], boolean bPrint) {
String tmpGrid[][];
int nMaxCols = 0;
int nRows = uniqueCount(strs);
int nGridRow = 0;
tmpGrid = new String [nRows][];
for (int nRow=0; nRow<nRows; nRow++) {
String cFilename = strs[nRow];
if (!cFilename.endsWith(".cmd") // just list unix files (filter for batch files)
&& cFilename.indexOf("-") > 0 ) // make sure there's a dash in the filename
{
String strTokens[] = tokenize(strs[nRow], "-"); // the dash is our token deliminator
int nCols = strTokens.length;
if (nCols>nMaxCols) nMaxCols=nCols;
tmpGrid[nGridRow] = new String [nCols];
for (int nCol=0; nCol<nCols; nCol++) {
tmpGrid[nGridRow][nCol] = strTokens[nCol];
if (bPrint) System.out.print(" "+tmpGrid[nGridRow][nCol]);
}
nGridRow++;
if (bPrint) System.out.println("");
} //end-if
}
String[][] cmdGrid = new String[nGridRow][nMaxCols];
System.arraycopy(tmpGrid, 0, cmdGrid, 0, nGridRow); // removes null rows (&NPEs!)
return cmdGrid;
}
这一返回的2-d array(下文),所以 grid[Row-N][Col-0]
是匹配的。我想拉只有不同的价值观里 row[0]
是通配符的匹配 cmdToken[0] && row[1]
是"像" cmdToken[1]
因此,我的用户可以拼凑起来的命令直到 "my du gr ?"
返回 "ENTER, [se314]"
-如果是有道理...
String[][] makeGrid:
mysql dump grid se314
mysql connect grid
mysql dump grid
mysql connect rds
我的挑战:我不能似乎把我的头在我的匹配功能。如果这是SQL它将是这样的:
"SELECT DISTINCT col2 FROM cmd_Grid
WHERE col1 LIKE 'cmdToken1%' "
或甚至更好:递归,设置一个int depthmark对每个连续柱
`SELECT DISTINCT col+str(depthmark+1) FROM cmd_Grid
WHERE col+str(depthmark) LIKE 'cmdMatchedTokens%' "
直到你有一个完全匹配。
我发现了一个包裹叫joSQL,我想出来的绝望,但我无法看来获得它的工作在Java6.无论如何:我也希望一个纯粹的java解决方案,使一切都可以被包含在单个类...
也许使用扫描仪或什么要分析我multidimentional列为独特的价值观...我知道我可能使它方式更加复杂,它需要。
一个温柔的微调,正确的方向,将不胜感激。
TIA
解决方案
一项详尽的方案可以是contruct一个哈希因此,关键是尽可能短的命令'我的同遗传资源"和相应的价值是"mysql-连接-网"。所以会有价值的散列的地图,将有"mysql-连接-格"的价值。
但是,这是一个可行的解决办法只有有限数量的可能钥匙。如果不是这种情况,然后可以使用的字符串分析方法。
例如:
String[][] makeGrid = new String[][]{{"mysql", "dump", "grid", "se314"},
{"mysql", "connect", "grid", ""},
{"mysql", "dump", "grid", ""},
{"mysql", "connect", "rds", ""}
};
String[] query2 = new String[]{"my", "du", "gr"};
String[][] matchingCommands = new String[4][4];
int resultSize = 0;
for(int i=0; i<makeGrid.length; i++)
{
String[] commandColumn = makeGrid[i];
boolean matches = false;
for(int cnt=0; cnt<commandColumn.length; cnt++)
{
String commandPart = commandColumn[cnt];
if(cnt < query2.length){
String queryPart = query2[cnt];
if(commandPart.startsWith(queryPart) || queryPart.equals("?")){
matches = true;
}else{
matches = false;
break;
}
}
}
if(matches){
matchingCommands[resultSize] = commandColumn;
resultSize++;
}
}
这段代码应该给你一些想法如何去做。有一点要注意在这里虽然。的 matchingCommands 阵列已经被初始化为4行4列,这是一种浪费,因为比赛将比较小的。让我知道如果你需要帮助使这个效率更高。否则,这是一个工作一段代码我认为不会你想要什么。
其他提示
你也可以看到用一些更先进的数据结构像对列表,而不是一系列和使用StringTokenizer以生成每个命令一部分的飞行。
它将是这样的:
ArrayList<String> matchingCommands = new ArrayList<String>();
ArrayList<String> commandList = new ArrayList<String>();
commandList.add("mysql dump grid se314");
commandList.add("mysql connect grid");
commandList.add("mysql dump grid");
commandList.add("mysql connect rds");
String queryCommand = "my du gr ?";
for(int i=0; i<commandList.size(); i++)
{
boolean matches = false;
String command = commandList.get(i);
StringTokenizer commandTokenizer = new StringTokenizer(command, " "); // Using space as the deliminator
StringTokenizer queryTokenizer = new StringTokenizer(queryCommand, " "); // Using space as the deliminator
while(commandTokenizer.hasMoreTokens())
{
String queryPart = queryTokenizer.nextToken();
String commandPart = commandTokenizer.nextToken();
if(commandPart.startsWith(queryPart) || queryPart.equals("?")){
matches = true;
}else{
matches = false;
break;
}
}
if(matches){
matchingCommands.add(command);
}
}
System.out.println(matchingCommands);
这将确保你的节目可以增长动态并没有浪费的记忆,因为空对象。
现在我玩弄周围与分析每个cmdString(查询)对空白符&切分阵列。是这样的:
Scanner sCmdString = new Scanner(cInput);
while (sCmdString.hasNext()) {
String cToken = sCmdString.next().toUpperCase().trim();
System.out.println(" "+cToken+" ");
// match cmdString[i..n] to cmdGrid
for (int nRow=0; nRow < cmdGrid.length; nRow++) {
for (int nCol=0; nCol < cmdGrid[nRow].length; nCol++) {
if (cmdGrid[nRow][nCol].equalsIgnoreCase(cToken) )
System.out.println("MATCH: "+cmdGrid[nRow][nCol]);
else System.out.println("NO MATCH:"+cmdGrid[nRow][nCol].toUpperCase()+":"+cToken+"...");
}
}
}
但我得到Npe与不均匀行的长度。
我喜欢你的想法的平行列。
我认为,我仍然必须消除重复...没有?