繁体   English   中英

如何在Linux终端上抑制或删除Java stdin中的转义代码字符

[英]How to suppress or remove escape code characters from Java stdin on Linux terminal

我在这里和其他地方都进行了一些研究,涵盖了这个问题的主题,并且发现jline3无疑是一个清晰的解决方案,并提供了许多重要的跨平台优势和功能。

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

这似乎无法通过Scanner来实现,而且我不确定如何使用Java将终端置于原始输入模式-如果有一种方法可以通过Shell脚本实现,则无法找到出了多远。 我正在使用一个基本的shell脚本来调用我的Java程序并传递一些系统属性,因此这也是一个很好的解决方案。

到目前为止,我已经使用了ByteBufferCharBufferDecoder等的组合,这些组合是从其他问题以及一些初步研究中看到的,但无法实现我想要的。

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

感谢您的协助或其他资源。

编辑/更新:

感谢大家对这个问题的回答。 最终,我正在研究一种几乎完全适合我想要的解决方案,并且是Java Console类及其正则表达式功能的组合。

下面是一个非常基本的框架。 approach where all characters are banned but the ones I compile into a Pattern which are allowed to be printed to the screen. 本质上,我选择了“ 禁止所有字符的方法,但是我将这些字符编译成一个Pattern ,然后允许将其打印到屏幕上。

of the game as I wanted the game to react to keys for "movement" and have the user be able to hit Enter and type out some command. 这也让我测试其他重要的输入键,例如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. 通过使用“空”字符(例如, char c = 0;重写输入的StringBuilder对象的字符并调整其大小,仍在使用退格功能,这最终可能根本行不通。

  2. 我一直无法找到一种方法来排除大写字母A,B,C和D,它们遵循表示箭头键的转义码序列,因此我不得不禁止所有大写字母。 我试图等到读者没有检测到更多输入,然后解析该输入,但未能成功实现该输入。

  3. 诸如插入和删除之类的特殊键会产生字符代码,其中包括仍可打印的数字。 我不确定在不禁止数字的情况下如何防止这种情况的发生(与箭头键和大写字母相同)。

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

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

根据需要更改正则表达式,以接受对或错的看法。

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;
}
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM