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

时间:2012-05-31 08:57:56

标签: 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);

现在,我希望输出为:

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

但相反,我得到了与输入完全相同的东西。也就是说,每个\ n都包含在输出中,并且所有内容都在一行而不是单独的行。

我认为Scanner能够正确读取转义字符,但它反而将它复制到字符串上,就像它是\ n。

3 个答案:

答案 0 :(得分:4)

不,Scanner不会为你做那件事。你必须自己做翻译。

(请注意,如果您使用类似sc.useDelimiter("\\\\n")的内容,则其他人建议您破解普通next()方法的功能,而nextLine()可能无法按预期运行。)

以下是我将如何解决它的草图:

更改

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

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

其中JavaEscapeReaderFilterReader扩展为{/ 3}}:

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

给定带有内容的输入文件

Line1\nLine2
Line3\nLine3

程序

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

打印

Line1
Line2
Line3
Line4

另一种选择是使用StringEscapeUtils.unescapeJava并对处理后的字符串进行后处理。

答案 1 :(得分:3)

如果\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());
    }

输出:

  

Hello World!

     

我一直试图让它工作一段时间。

     

令人沮丧。

编辑:

如果您想阅读文件并将文本中的\n替换为实际EOL。你可以简单地使用:

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

答案 2 :(得分:2)

您可以使用Scanner.useDelimiter设置自己的分隔符。在您的情况下使用双引号\\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.