我正在尋找關於如何驗證用戶輸入驗證的建議。我的任務是根據用戶的文本輸入執行命令。我唯一擔心的是可以有許多可以接受的命令變體。驗證輸入java的最佳實踐
例如,這些命令都是可以接受的,做同樣的事情,「展示遊戲板」
SH板,
抄板,
顯示板,
展博,
笑波,
SH波
大約有10共享此類似PROPERT其它命令因此我想知道驗證用戶輸入的最佳做法是什麼?
我應該將所有不同的組合存儲在散列表中嗎?
我正在尋找關於如何驗證用戶輸入驗證的建議。我的任務是根據用戶的文本輸入執行命令。我唯一擔心的是可以有許多可以接受的命令變體。驗證輸入java的最佳實踐
例如,這些命令都是可以接受的,做同樣的事情,「展示遊戲板」
SH板,
抄板,
顯示板,
展博,
笑波,
SH波
大約有10共享此類似PROPERT其它命令因此我想知道驗證用戶輸入的最佳做法是什麼?
我應該將所有不同的組合存儲在散列表中嗎?
查看正則表達式(正則表達式)。當你想使用不一定完整的值時,這些非常有用。
例如: 說我鍵入「shutdo」 用正則表達式,你可以使你的程序明白,字符串「SHUTD」後,什麼手段來關機()
我完全不同意你的看法。這是一個簡單的詞法分析器的工作,部分可能用正則表達式編寫,但將正則表達式看作是可能有10個命令的系統的解決方案,每個命令可能需要大約5個不同的參數......這將是完全無法管理的權利從頭開始。 –
如果命令是非常具體的和有限的,我只是將它們全部添加到某個數據結構中(哈希就是其中之一)。
如果問題在於你應該理解用戶輸入應該做什麼,那麼我會說使用正則表達式或簡單模式驗證來查找模式(看起來他們都是兩個單詞,第一個以「sh」開頭,第二個以「bo」開頭)。
但說實話,〜15個命令在空間/效率方面並不是那麼重要。
編輯:
大約有10共享此類似性質
如果這意味着10 更命令,如「顯示板」等命令,那麼我會說商店它在散列。但是如果我誤解了你的意思,並且你的意思是說有10個其他命令可以做類似的事情(「set piece」,「set pie」,「se pi」等),那麼正則表達式就是要走的路。
看起來允許長度最小的命令是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;
}
}
如果我正確理解了你,那麼有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
包含所有可能的命令。
輸入命令的每個部分都被檢查,如果它是一個可用命令的開始。
您可以使用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));
}
}
將所有有效組合放在散列表中將會非常快速地變得笨重,並且在碰到更有效的組合時,您還必須不斷更新它。您可以通過向用戶提供一組固定的命令來執行更嚴格的操作,或讓他選擇與命令相對應的數字。 Reg ex是另一種更可行的解決方案。 – Siddhartha
我完全明白你在說什麼,這就是爲什麼我問,我不希望它很笨重。不幸的是,我不能限制這些命令。練習的目的是能夠處理所有變化。 – fatalError
我明白了。我發佈了一小段代碼,幫助您開始使用。 – Siddhartha