如何在Linux终端上禁止或删除Java stdin中的转义码字符

问题描述 投票:1回答:2

我已经在这里和其他地方做了一些研究,讨论了这个问题的话题,我发现了jline3,它肯定是一个明确的解决方案,并提供了大量重要的跨平台优势和功能。

但是,作为一种更好地理解Java如何使用流读取器和输入(包括原始字节)以及在Linux终端中实现基于文本的基本冒险游戏的方法,我希望能够抑制或删除箭头键用户输入时来自stdin的转义码。

这似乎不可能通过Scanner,我不确定如何使用Java将终端置于原始输入模式 - 如果有办法通过shell脚本实现,我一直无法找到到目前为止如何。我正在使用一个基本的shell脚本来调用我的Java程序并传入一些系统属性,因此这也是一个很好的解决方案。

到目前为止,我已经使用了ByteBufferCharBufferDecoder等的组合,我从其他问题和一些初步研究中看到过,但是我无法实现我正在寻找的东西。

我怎么能简单地让我的Java程序等待用户输入而不显示或捕获箭头键转义字符(例如,^[[A^[[B)?

感谢您提供任何帮助或其他资源。

编辑/更新:

感谢所有投诉他们回答这个问题的人。最终,我正在研究一种几乎完全符合我想要的解决方案,它是Java Console类及其正则表达式功能的组合。

下面是一个非常基本的框架。基本上我选择了排除所有,包括一些禁止所有字符但我编译成Pattern的方法,允许打印到屏幕上。

这也让我测试其他重要的输入键,如Enter进入和退出游戏的命令模式,因为我希望游戏对“移动”键做出反应,并让用户能够按Enter键并键入一些命令。

我不得不摆弄stty以允许这个解决方案,Java应用程序通过bash脚本启动。

Bash脚本:

#!/bin/bash

# Save current terminal settings
STTY_SAVE=$(stty -g)

# Disable need to press [Enter] in order to have input processed
stty cbreak
# Disable the echoing of input
stty -echo
# Tell the terminal that erasure on the console should produce a backspace cursor movement
stty erase ^H

# Execute application
java reader_testing.Main

# Restore saved terminal settings
stty $STTY_SAVE
exit 0

注意:stty erase ^H似乎也允许Java中的Console在* nix操作系统上捕获退格键字符代码\010。如果没有该行,它似乎执行删除(?)

Java代码:

Console console = System.console();    

int symbol = 0;
char character = 0;

String matchString = new String();
StringBuilder input = new StringBuilder();

Pattern allowed = Pattern.compile( "[a-z0-9 !@#$%^&*()_+-=]" );
Matcher matcher = null;

while ( true ) { // This is an arbitrary loop for the example
    try {
        symbol = console.reader().read();

        if ( symbol == 10 ) { // 10 = Enter
            break;
        }

        character = (char) symbol;

        matchString = Character.toString( character );

        matcher = allowed.matcher( matchString );

        if ( matcher.find() ) {
            input.append( character );

            System.out.print( "\r" + input );
        }
    } catch ( IOException e ) {
        e.printStackTrace();
    }
}

System.out.println( "\nYou entered: " + input );

问题:

  1. 仍在研究退格功能,用“空”字符重写输入StringBuilder对象的字符(例如,char c = 0;并调整它。这可能最终根本不起作用。
  2. 我无法找到一种方法来排除跟随表示箭头键的转义码序列的大写A,B,C和Ds,所以我不得不禁止所有大写字母。我试图等到读者不再检测到输入,然后解析该输入,但未能成功实现。
  3. “插入”和“删除”等特殊键会生成包含仍可打印的数字的字符代码。我不确定如何在不禁止数字的情况下防止这种情况发生(与箭头键和大写字母的问题相同)。

最后,这一切都不会起作用或相当有限,但是玩这个很有趣,如果情况更糟,我可以让退格键擦除整个输入字符串。键入命令不是游戏的主要方面。

java terminal stdin
2个回答
0
投票

您可以使用java.io.Console类。 Console.writer()自动处理基础字符编码。 Console.readLine()从用户检索单行文本,并等待他按Enter键终止。还有一些其他方法可以帮助您制作命令行游戏。


0
投票

根据您的需要更改正则表达式,以接受您认为对或错的内容。

public class PasscodeScanner {

 public static void main(String args[]) {

    Scanner key = new Scanner(System.in);
    while(getInput(key)) {
        //keep doing until we you're good
    }
    System.out.println("Congrats, you're good.");
}

private static boolean getInput(Scanner key) {
    System.out.print("Enter your passcode: ");
    String sentence = key.nextLine();
    if(validate(sentence)) {
        System.out.println("You are cleared");
        return false;
    }
    return true;
}

private static boolean validate(String entered) {
    //change regex as per your need
    Pattern pattern = Pattern.compile("[a-z]");
    Matcher matcher = pattern.matcher(entered);
    if (matcher.find()) {
        return true;
    }
    return false;
}
}
© www.soinside.com 2019 - 2024. All rights reserved.