如何使扫描仪正确读取转义字符?
我正在读取一个文件,该文件在一行中读取所有内容:
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一样。
如果\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()); }
输出:
你好,世界!
我一直试图让它工作一段时间。
令人沮丧。
编辑:
如果要读取文件并将文本中的\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"))); }
不, Scanner
不会为你做那件事。 你必须自己做翻译。
(请注意,如果您使用sc.useDelimiter("\\\\n")
,则其他人建议您破坏普通next()
方法的function,而nextLine()
可能无法按预期运行。)
这是我如何解决它的草图:
更改
Scanner input = new Scanner(new FileReader(fileName));
至
Scanner input = new Scanner(new JavaEscapeReader(new FileReader(fileName))); ^^^^^^^^^^^^^^^^^^^^^ ^
JavaEscapeReader
将扩展FilterReader
如下所示:
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
并对读取字符串进行后处理。
您可以使用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.