首页 > 解决方案 > 用 Java 模拟 SQL shell 模拟器

问题描述

我想用 Java 模拟一个模拟 SQL shell。我们的想法是我们键入一行文本并终止它,;然后按 enter 将行打印回控制台。

这应该能够接受多行文本,并且一旦有;回车符,它应该打印出文本。

这是我的代码:

while(true){
      Scanner scanner = new Scanner(System.in).useDelimiter(";");
      StringBuilder builder = new StringBuilder();
      while(scanner.hasNextLine()){
         if(scanner.nextLine().endsWith(";")){
            builder.append(scanner.nextLine());
            break;
          }else{
            builder.append(scanner.nextLine());
          }

          }
            System.out.println(builder.toString());
        }

这不起作用,因为它永远不会退出内部 while 循环。

标签: java

解决方案


仅供参考: nextLine()读取lines,而不是tokens,因此您的代码没有使用分隔符。

您需要使用next()来读取令牌,并且您现在已经意识到,您需要一些条件来结束循环。

结束 shell 的常用方法是exit命令。

由于您希望语句以;回车结尾,因此您需要为此调整分隔符。为了更加宽松,在;(正则表达式:\h水平空白字符)之后允许空格,并匹配换行符,而不仅仅是回车(正则表达式:\R任何 Unicode 换行符序列)。

此外,您需要创建Scanner 外部任何循环。

Scanner scanner = new Scanner(System.in).useDelimiter(";\\h*\\R");
for (;;) {
    System.out.print(">");
    if (! scanner.hasNext())
        break;
    String stmt = scanner.next();
    stmt = stmt.replaceAll("(?mU:^\\s+\\R)|(?U:\\s+$)", ""); // remove blank lines and trailing spaces
    if (stmt.equals("exit"))
        break;
    System.out.println("Received command: " + stmt);
}
System.out.println("Done!");

样本输出

>test;
Received command: test
> This is a

multi-line test

with blank lines

          ;
Received command:  This is a
multi-line test
with blank lines
>
;
Received command: 
>exit;
Done!

推荐阅读