Java Scanner问题

11
你如何将Scanner的分隔符设置为分号或换行符?
我尝试过: Scanner.useDelimiter(Pattern.compile("(\n)|;")); 但它没有起作用。

发现了一个错误,我必须使用 (\r\n)|;。我正在解析类似于这样的内容:string;number\r\n... 但它没有将 100\r 视为数字。 - Razvi
3个回答

16
作为一般规则,在模式中,需要将 \ 加倍使用。

因此,请尝试:

Scanner.useDelimiter(Pattern.compile("(\\n)|;"));
或者
Scanner.useDelimiter(Pattern.compile("[\\n;]"));

编辑: 如果 \r\n 是问题所在,你可以尝试这样做:

Scanner.useDelimiter(Pattern.compile("[\\r\\n;]+"));

这将匹配一个或多个字符:\r\n;

注意:我还没有尝试过这些。


1
你可以选择任何一种方式。如果你使用两个反斜杠,正则表达式编译器会将\n解释为换行符的转义序列。如果你只使用一个反斜杠,正则表达式编译器会将其视为实际的换行符,并将其与文本中的换行符进行匹配。但我肯定会选择字符类版本:"[\\n;]""[\n;]";这样更易于阅读,也更高效。 - Alan Moore
@Alan Moore:啊,好的...我只是假设一个文字换行会被误解。 - Powerlord

9

如您所发现的那样,您需要寻找DOS/网络风格的\r\n(CRLF)行分隔符,而不是Unix风格的\n (仅LF)。但如果文本同时包含两者怎么办?这种情况经常发生;事实上,当我查看此页面源代码时,我看到两种变体。

您应该习惯寻找这两种分隔符,以及旧版Mac风格的\r(仅CR)。以下是一种方法:

\r?\n|\r

将其插入到您的示例代码中,您将得到:
scanner.useDelimiter(";|\r?\n|\r");

假设您希望每次仅匹配一个换行符或分号。如果您想匹配一个或多个,可以使用以下方法:

scanner.useDelimiter("[;\r\n]+");

同时请注意,我传递了一个正则表达式字符串而不是一个Pattern对象;所有的正则表达式都会自动缓存,因此预编译正则表达式并不能提高性能。


1

从楼主的评论来看,似乎是换行符(\r\n或CRLF)不同导致了问题。

这是我的答案,可以处理多个分号和任何格式的换行符(可能需要,也可能不需要)。

Scanner.useDelimiter(Pattern.compile("([\n;]|(\r\n))+"));

例如,一个长这样的输入文件:
1


2;3;;4
5

会得到1,2,3,4,5的结果

我尝试了普通的\n和\\n - 在我的情况下两者都可以工作,尽管我同意如果你需要一个正常的反斜杠,你应该把它加倍,因为它是一个转义字符。恰好在这种情况下,"\n"成为所需的字符,无论有没有额外的 '\'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接