我如何使用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.Scanner
validation输入 – 有许多用法示例 - 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]+");
无论输入中的行分隔符是什么,这都应该有效,并且将忽略空行。