我的Java非常生疏,我只能尝试创建一个用户界面来简化shell脚本或批处理文件的执行,这取决于它分别是Linus还是Win32。这些文件具有以下命名约定。
module-verb-object-etc [args-list]
mysql-connect-grid
mysql-connect-rds
mysql-dump-grid
mysql-dump-grid-se314最后,我希望它能够解析明确的术语,这样我就可以:
我编写了一个函数来从目录中提取文件列表&重新创建一个文件数组。然后,使用下面的方法将其转换为二维数组,返回一个动态大小的潜在命令网格。
/**********************************************************************************
* 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;
}这将返回一个二维数组(如下所示),因此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我的挑战:在java中,我似乎无法理解matcher函数。如果是SQL,则如下所示:
"SELECT DISTINCT col2 FROM cmd_Grid
WHERE col1 LIKE 'cmdToken1%' " 或者更好:递归地为每个连续列设置一个int深度标记
`SELECT DISTINCT col+str(depthmark+1) FROM cmd_Grid
WHERE col+str(depthmark) LIKE 'cmdMatchedTokens%' " 直到你找到了完全匹配的人。
我发现了一个名为joSQL的包,我出于绝望而尝试了它,但我似乎无法让它在Java6中工作。无论如何:我还希望有一个纯java解决方案,这样所有的东西都可以包含在一个类中.
也许用扫描仪或者什么东西来解析我的多维数组来得到唯一的值.我知道我可能让事情变得更复杂了。
在正确的方向上轻轻地推一下会更好。
提亚
发布于 2010-01-19 01:10:45
一个详尽的解决方案可能是构造一个hashMap,这样键可能是一个简短的命令,比如'my gr‘,相应的值是“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列,这是浪费的,因为匹配比这要小。如果你需要帮助让这个更有效率的话请告诉我。否则,这是一个工作的代码,我认为它可以做你想要的。
发布于 2010-01-19 17:47:13
您还可以考虑使用一些更高级的数据结构,比如ArrayList,而不是数组,并使用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);这将确保您的程序能够动态增长,并且也不会因为空对象而浪费内存。
发布于 2010-01-19 02:13:03
现在,我正在为空白分隔符解析每个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+"...");
}
}
}但我得到的NPEs的长度参差不齐。
我喜欢你把柱子压平的想法。
我想我还是得把重复的.不是吗?
https://stackoverflow.com/questions/2090166
复制相似问题