[英]How do I use System.getProperty("line.separator").toString()?
我有一个传递给我的方法的制表符分隔的字符串(代表一个表)。 当我将它打印到命令行时,它看起来像一个带有行的表:
https://i.stack.imgur.com/2fAyq.gif
命令窗口已正确缓冲。 我的想法是每行之前或之后肯定有一个换行符。
我的问题是我想将传入的字符串拆分为代表表行的单个字符串。 到目前为止,我有:
private static final String newLine = System.getProperty("line.separator").toString();
private static final String tab = "\t";
private static String[] rows;
...
rows = tabDelimitedTable.split(newLine); //problem is here
System.out.println();
System.out.println("################### start debug ####################");
System.out.println((tabDelimitedTable.contains(newLine)) ? "True" : "False");
System.out.println("#################### end debug###################");
System.out.println();
输出:
################### start debug ####################
False
#################### end debug###################
显然,字符串中有一些东西告诉操作系统开始一个新行。 然而它显然不包含换行符。
在 Windows XP SP3 上运行最新的 JDK。
有任何想法吗?
您不能假设任意输入文本文件使用“正确的”特定于平台的换行符。 这似乎是您问题的根源; 它与正则表达式关系不大。
举例说明,在 Windows 平台上, System.getProperty("line.separator")
为"\\r\\n"
(CR+LF)。 然而,当你在这个平台上运行你的 Java 代码时,你很可能不得不处理一个行分隔符只是"\\n"
(LF)的输入文件。 也许这个文件最初是在 Unix 平台上创建的,然后以二进制(而不是文本)模式传输到 Windows。 在许多情况下,您可能会遇到这些情况,您必须将文本文件解析为不使用当前平台的换行符的输入。
(巧合的是,当 Windows 文本文件以二进制模式传输到 Unix 时,许多编辑器会显示^M
,这让一些不明白发生了什么的人感到困惑)。
当您生成文本文件作为输出时,您可能应该更喜欢特定于平台的换行符,但是当您使用文本文件作为输入时,假设它正确使用特定于平台的换行符可能并不安全。
解决问题的一种方法是使用例如java.util.Scanner
。 它有一个nextLine()
方法,可以返回下一行(如果存在),正确处理平台的换行符和输入文本文件之间的任何不一致。
您还可以组合 2 Scanner
,一个是逐行扫描文件,另一个是扫描每行的标记。 这是一个简单的用法示例,它将每一行分成一个List<String>
。 因此整个文件变成了一个List<List<String>>
。
这可能比将整个文件读入一个巨大的String
然后split
成行(然后split
成部分)更好的方法。
String text
= "row1\tblah\tblah\tblah\n"
+ "row2\t1\t2\t3\t4\r\n"
+ "row3\tA\tB\tC\r"
+ "row4";
System.out.println(text);
// row1 blah blah blah
// row2 1 2 3 4
// row3 A B C
// row4
List<List<String>> input = new ArrayList<List<String>>();
Scanner sc = new Scanner(text);
while (sc.hasNextLine()) {
Scanner lineSc = new Scanner(sc.nextLine()).useDelimiter("\t");
List<String> line = new ArrayList<String>();
while (lineSc.hasNext()) {
line.add(lineSc.next());
}
input.add(line);
}
System.out.println(input);
// [[row1, blah, blah, blah], [row2, 1, 2, 3, 4], [row3, A, B, C], [row4]]
尝试
rows = tabDelimitedTable.split("[" + newLine + "]");
这应该可以解决正则表达式问题。
也不是那么重要,但返回类型
System.getProperty("line.separator")
是字符串所以不需要调用 toString()。
试试BufferedReader.readLine()
而不是所有这些复杂的事情。 它将识别所有可能的行终止符。
我认为您的问题是String.split()
将其参数视为正则表达式,而正则表达式则专门处理换行符。 您可能需要显式创建一个正则表达式对象以传递给split()
(它还有另一个重载)并通过在Pattern.compile()
的标志参数中传递MULTILINE
来配置该正则表达式以允许换行。 文档
其他响应者认为 split() 将正则表达式作为参数是正确的,因此您必须先解决这个问题。 另一个问题是您假设换行符与系统默认值相同。 根据数据来自何处以及程序在何处运行,此假设可能不正确。
尝试这个:
rows = tabDelimitedTable.split("[\\r\\n]+");
无论输入中的行分隔符如何,这都应该有效,并且将忽略空行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.