2015-10-16 210 views
1

我正在尋找關於如何驗證用戶輸入驗證的建議。我的任務是根據用戶的文本輸入執行命令。我唯一擔心的是可以有許多可以接受的命令變體。驗證輸入java的最佳實踐

例如,這些命令都是可以接受的,做同樣的事情,「展示遊戲板」

SH板,
抄板,
顯示板,
展博,
笑波,
SH波

大約有10共享此類似PROPERT其它命令因此我想知道驗證用戶輸入的最佳做法是什麼?

我應該將所有不同的組合存儲在散列表中嗎?

+2

將所有有效組合放在散列表中將會非常快速地變得笨重,並且在碰到更有效的組合時,您還必須不斷更新它。您可以通過向用戶提供一組固定的命令來執行更嚴格的操作,或讓他選擇與命令相對應的數字。 Reg ex是另一種更可行的解決方案。 – Siddhartha

+0

我完全明白你在說什麼,這就是爲什麼我問,我不希望它很笨重。不幸的是,我不能限制這些命​​令。練習的目的是能夠處理所有變化。 – fatalError

+0

我明白了。我發佈了一小段代碼,幫助您開始使用。 – Siddhartha

回答

1

查看正則表達式(正則表達式)。當你想使用不一定完整的值時,這些非常有用。

例如: 說我鍵入「shutdo」 用正則表達式,你可以使你的程序明白,字符串「SHUTD」後,什麼手段來關機()

+0

我完全不同意你的看法。這是一個簡單的詞法分析器的工作,部分可能用正則表達式編寫,但將正則表達式看作是可能有10個命令的系統的解決方案,每個命令可能需要大約5個不同的參數......這將是完全無法管理的權利從頭開始。 –

0

如果命令是非常具體的和有限的,我只是將它們全部添加到某個數據結構中(哈希就是其中之一)。

如果問題在於你應該理解用戶輸入應該做什麼,那麼我會說使用正則表達式或簡單模式驗證來查找模式(看起來他們都是兩個單詞,第一個以「sh」開頭,第二個以「bo」開頭)。

但說實話,〜15個命令在空間/效率方面並不是那麼重要。

編輯:

大約有10共享此類似性質

如果這意味着10 命令,如「顯示板」等命令,那麼我會說商店它在散列。但是如果我誤解了你的意思,並且你的意思是說有10個其他命令可以做類似的事情(「set piece」,「set pie」,「se pi」等),那麼正則表達式就是要走的路。

0

看起來允許長度最小的命令是2 因此首先要檢查期限的長度至少是2

接下來,你可以遍歷可用的命令, 並在停止首先以該詞開頭,例如:

List<String> commands = Arrays.asList("show", "create", "delete"); 
for (String command : commands) { 
    if (command.startsWith(term)) { 
     // found a match, command is: command 
     break; 
    } 
} 
0

如果我正確理解了你,那麼有N個不同的命令可以組合。只要它保持明確,應允許縮寫每個命令。

如果是這種情況,則下面的方法expandCommands(String)expandCommand(String)將標準化每個命令部分。

public class Main { 
    static Set<String> availableCommands = new HashSet<>(Arrays.asList(
      "show", 
      "board", 
      "btest" 
    )); 


    public static void main(String[] args) throws Exception { 
     List<String> testData = Arrays.asList(
       "sh board", 
       "sho board", 
       "show board", 
       "show bo", 
       "sho bo", 
       "sh bo" 
     ); 


     String expected = "show board"; 
     for (String test : testData) { 
      String actual = expandCommands(test); 

      if (!expected.equals(actual)) { 
       System.out.println(test + "\t"+ actual); 
      } 

     } 


     try { 
      expandCommands("sh b"); 
      throw new IllegalStateException(); 
     } catch (Exception e) { 
      if (!"not unique command: b".equals(e.getMessage())) { 
       throw new Exception(); 
      } 
     } 

     try { 
      expandCommands("sh asd"); 
      throw new IllegalStateException(); 
     } catch (Exception e) { 
      if (!"unknown command: asd".equals(e.getMessage())) { 
       throw new Exception(); 
      } 
     } 


    } 

    private static String expandCommands(String aInput) throws Exception { 
     final String[] commandParts = aInput.split("\\s+"); 


     StringBuilder result = new StringBuilder(); 

     for (String commandPart : commandParts) { 
      String command = expandCommand(commandPart); 

      result.append(command).append(" "); 
     } 


     return result.toString().trim(); 
    } 

    private static String expandCommand(final String aCommandPart) throws Exception { 
     String match = null; 

     for (String candidate : availableCommands) { 
      if (candidate.startsWith(aCommandPart)) { 
       if (match != null) { 
        throw new Exception("not unique command: " + aCommandPart); 
       } 

       match = candidate; 
      } 
     } 


     if (match == null) { 
      throw new Exception("unknown command: " + aCommandPart); 
     } 

     return match; 
    } 

} 

Set<String> availableCommands包含所有可能的命令。

輸入命令的每個部分都被檢查,如果它是一個可用命令的開始。

0

您可以使用reg-ex匹配來驗證輸入。例如,下面的模式將匹配以sh後跟0個或多個字符開頭的任何內容,然後是space,然後是bo,後面是0個或更多個字符。

public class Validator { 
    public static void main (String[] args) { 
    String pattern = "sh[\\w]* bo[\\w]*"; 
    System.out.println(args[0].matches(pattern)); 
    } 
}