Java 如何使扫描仪正确读取转义字符?

Java 如何使扫描仪正确读取转义字符?,java,java.util.scanner,Java,Java.util.scanner,我从一个文件中读取的内容类似于一行中的所有内容: Hello World!\nI've been trying to get this to work for a while now.\nFrustrating.\n 我的扫描仪从文件中读取并将其放入字符串中: Scanner input = new Scanner(new File(fileName)); String str = input.nextLine(); System.out.print(str); 现在,我希望输出为: Hel

我从一个文件中读取的内容类似于一行中的所有内容:

Hello World!\nI've been trying to get this to work for a while now.\nFrustrating.\n
我的扫描仪从文件中读取并将其放入字符串中:

Scanner input = new Scanner(new File(fileName));
String str = input.nextLine();
System.out.print(str);
现在,我希望输出为:

Hello World!
I've been trying to get this work for a while now.
Frustrating.
但是我得到的是与输入完全相同的东西。也就是说,每个\n都包含在输出中,并且所有内容都在一行上,而不是在单独的行上


我原以为Scanner能够正确读取转义字符,但它将转义字符复制到字符串上,就像\\n.

不,
Scanner
不会为您这样做。你得自己翻译

(请注意,如果您像其他人建议的那样使用类似于
sc.usedimiter(\\\\n”)
的东西,您正在破坏普通
next()
方法的功能,并且
nextLine()
可能无法按预期工作。)

下面是我将如何解决它的示意图:

改变

Scanner input = new Scanner(new FileReader(fileName));

其中
JavaEscapeReader
的扩展如下:

class JavaEscapeReader extends FilterReader {

    JavaEscapeReader(Reader in) {
        super(in);
    }

    @Override
    public int read() throws IOException {
        int ch = super.read();
        switch (ch) {
        case '\\':
            switch (super.read()) {
            case '\\': return '\\';
            case 'n': return '\n';
            case 't': return '\t';
            case 'f': return '\f';
            // ...
            default:
                throw new IOException("Invalid char sequence.");
            }
        default:
            return ch;
        }
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int i = 0, ch;
        while (i < len && -1 != (ch = read()))
            cbuf[i++] = (char) ch;
        return i == 0 ? -1 : i;
    }
}
节目

Scanner sc = new Scanner(new JavaEscapeReader(new FileReader("filename.txt")));
while (sc.hasNextLine())
    System.out.println(sc.nextLine());
印刷品

Line1
Line2
Line3
Line4

另一个选项是使用和后处理读取的字符串。

您可以使用设置自己的分隔符。在您的情况下,使用双引号
\\n

s.useDelimiter("\\\\n");
例如:

Scanner s = new Scanner("Hello World!\\nI've been trying to get this to " +
                        "work for a while now.\\nFrustrating.\\n");
s.useDelimiter("\\\\n");

System.out.println(s.next());
System.out.println(s.next());
System.out.println(s.next());
产出:

Hello World!
I've been trying to get this to work for a while now.
Frustrating.

如果写入了
\n
,则不能使用
nextLine()
,因为没有
\n
(行尾),而是有
\\n
(两个字符)

请改为使用分隔符:

    Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt"));
    sc.useDelimiter("\\\\n");
    while(sc.hasNext()){
        System.out.println(sc.next());
    }
输出:

你好,世界

我已经试着让它工作了一段时间了

令人沮丧

编辑:

如果要读取文件并用实际EOL替换文本中的
\n
。您可以简单地使用:

Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt"));

//loop over real EOL
while(sc.hasNextLine()){

     //Replace the `\n` in the line with real EOL.
     System.out.println(sc.nextLine().replace("\\n", System.getProperty("line.separator")));
}

假设我需要将输入存储在字符串中,以便将来使用。有什么方法可以直接进入System.out正确存储转义字符吗?
    Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt"));
    sc.useDelimiter("\\\\n");
    while(sc.hasNext()){
        System.out.println(sc.next());
    }
Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt"));

//loop over real EOL
while(sc.hasNextLine()){

     //Replace the `\n` in the line with real EOL.
     System.out.println(sc.nextLine().replace("\\n", System.getProperty("line.separator")));
}