验证输入java的最佳实践
我正在寻找关于如何验证用户输入验证的建议。我的任务是根据用户的文本输入执行命令。我唯一担心的是可以有许多可以接受的命令变体。验证输入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