【问题标题】:best practice to validate input java验证输入 java 的最佳实践
【发布时间】:2015-10-16 18:31:00
【问题描述】:

我正在寻找有关如何验证用户输入的建议。我的任务是根据用户的文本输入执行命令。我唯一担心的是可以接受的命令有很多变体。

例如这些命令都是可以接受的并且做同样的事情,“显示游戏板”

sh 板,
展板,
展示板,
秀博,
肖博,

大约有 10 个其他命令共享此类似属性,所以我想知道验证用户输入的最佳实践是什么?

我应该将所有不同的组合存储在哈希图中吗?

【问题讨论】:

  • 把所有有效的组合放在一个哈希图中会很快变得笨拙,当你遇到更多有效的组合时,你还必须不断更新它。您可以通过为用户提供一组固定的命令来执行更严格的操作,或者让他选择与命令相对应的数字。 Reg ex 是另一种更可行的解决方案。
  • 我完全明白你在说什么,这就是我要问的原因,我不希望它笨拙。不幸的是,我不允许限制命令。练习的目的是能够处理所有的变化。
  • 我明白了。我发布了一些 reg ex sn-p 来帮助您入门。
  • OP,很好奇你最后是怎么做到的。
  • 我最终使用 switch 语句来测试第一个单词,并在其中嵌套了第二个 switch 语句来测试第二个单词。

标签: java validation input hashmap


【解决方案1】:

查看正则表达式(正则表达式)。当您想要使用不一定完整的值时,这些非常有用。

例如: 假设我输入“shutdo” 使用正则表达式,您可以让您的程序理解字符串“shutd”之后的任何内容都意味着 powerOff()

【讨论】:

  • 我完全不同意你的观点。这是一个简单的词法分析器的工作,它的一部分可能是用正则表达式编写的,但是将正则表达式视为一个系统的解决方案,它可能有 10 个命令,每个命令可能需要大约 5 个不同的参数......这将是完全无法管理的权利从一开始。
【解决方案2】:

看起来允许的最小命令长度是 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;
    }
}

【讨论】:

    【解决方案3】:

    如果命令非常具体和有限,我会将它们全部添加到某个数据结构中(哈希是其中之一)。

    如果问题是您应该了解用户输入应该做什么,那么我会说使用正则表达式或简单的模式验证来查找模式(看起来它们都是两个词,首先开始以“sh”和第二个以“bo”开头)。

    但老实说,就空间/效率而言,大约 15 个命令并不是什么大问题。

    编辑:

    大约有 10 个其他命令具有相同的属性

    如果这意味着 10 个 更多 命令,例如“show board”,那么我会说将其存储在哈希中。但如果我误解了你,你的意思是有 10 个其他命令可以做类似的事情(“set piece”、“set pie”、“se pi”等),那么 RegEx 就是要走的路。

    【讨论】:

      【解决方案4】:

      如果我理解正确的话,有 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&lt;String&gt; availableCommands 包含所有可能的命令。

      检查输入命令的每一部分,如果它恰好是一个可用命令的开始。

      【讨论】:

        【解决方案5】:

        您可以使用正则表达式匹配来验证输入。例如,下面的模式将匹配以 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));
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2016-01-09
          • 1970-01-01
          • 1970-01-01
          • 2014-04-19
          • 2015-10-20
          • 1970-01-01
          • 2020-07-07
          • 1970-01-01
          • 2011-09-24
          相关资源
          最近更新 更多