我如何使用System.getProperty(“line.separator”)。toString()?

我有一个Tab-delimited字符串(表示一个表),传递给我的方法。 当我将它打印到命令行时,它看起来像一个包含行的表:

http://sofzh.miximages.com/java/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。

有任何想法吗?

尝试

 rows = tabDelimitedTable.split("[" + newLine + "]"); 

这应该解决正则表达式问题。

也不是那么重要但返回类型

 System.getProperty("line.separator") 

String所以不需要调用toString()。

问题

不能假设任意输入文本文件使用“正确的”特定于平台的换行符分隔符。 这似乎是你问题的根源; 它与正则表达式几乎没有关系。

为了说明,在Windows平台上, System.getProperty("line.separator")"\r\n" (CR + LF)。 但是,当您在此平台上运行Java代码时,您可能必须处理其行分隔符只是"\n" (LF)的输入文件。 也许这个文件最初是在Unix平台上创建的,然后以二进制(而不是文本)模式传输到Windows。 可能存在许多情况,您可能遇到这种情况,您必须将文本文件解析为不使用当前平台的换行符分隔符的输入。

(巧合的是,当Windows文本文件以二进制模式传输到Unix时,许多编辑器会显示^M ,这使一些不理解发生了什么的人感到困惑)。

当您生成文本文件作为输出时,您可能更喜欢特定于平台的换行符分隔符,但是当您使用文本文件作为输入时,假设它正确使用特定于平台的换行符分隔符可能并不安全。


解决方案

解决问题的一种方法是使用例如java.util.Scanner 。 它有一个nextLine()方法,可以返回下一行(如果存在),正确处理平台的换行符分隔符和输入文本文件之间的任何不一致。

您还可以组合2个Scanner ,一个用于逐行扫描文件,另一个用于扫描每行的标记。 这是一个简单的用法示例,将每行分成List 。 因此整个文件成为List>

这可能是一种比将整个文件读入一个巨大的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 ABC // row4 List> input = new ArrayList>(); Scanner sc = new Scanner(text); while (sc.hasNextLine()) { Scanner lineSc = new Scanner(sc.nextLine()).useDelimiter("\t"); List line = new ArrayList(); 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]] 

也可以看看

  • Effective Java 2nd Edition,Item 25:首选列表到数组

相关问题

  • 使用java.util.Scannervalidation输入 – 有许多用法示例
  • Scanner vs. StringTokenizer vs. String.Split

尝试使用BufferedReader.readLine()而不是所有这些复杂function。 它将识别所有可能的行终止符。

在Windows上,line.separator是CR / LF组合( 此处参考)。

Java String.split()方法采用正则表达式 。 所以我认为这里有一些混乱。

我认为你的问题是String.split()将其参数视为正则表达式,并且正则表达式专门处理换行符。 您可能需要显式创建一个正则表达式对象以传递给split() (还有另一个重载)并通过在Pattern.compile()的flags参数中传递MULTILINE来配置该正则表达式以允许换行。 文件

其他响应者是正确的,split()采用正则表达式作为参数,所以你必须先修复它。 另一个问题是您假设换行符与系统默认值相同。 根据数据的来源以及程序运行的位置,此假设可能不正确。

尝试这个:

 rows = tabDelimitedTable.split("[\\r\\n]+"); 

无论输入中的行分隔符是什么,这都应该有效,并且将忽略空行。