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

Java 如何使用System.getProperty(“line.separator”).toString()?,java,eol,Java,Eol,我有一个以制表符分隔的字符串(表示一个表),它被传递给我的方法。当我将其打印到命令行时,它看起来像一个包含行的表: 命令窗口已正确缓冲。我的想法是,在每行之前或之后肯定有一个新行字符 我的问题是,我想将传入的字符串拆分为表示表行的单个字符串。到目前为止,我已经: private static final String newLine = System.getProperty("line.separator").toString(); private static final

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

命令窗口已正确缓冲。我的想法是,在每行之前或之后肯定有一个新行字符

我的问题是,我想将传入的字符串拆分为表示表行的单个字符串。到目前为止,我已经:

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###################
很明显,字符串中有某种东西告诉操作系统开始新的一行。但它显然不包含换行符

在WindowsXPSP3上运行最新的JDK


有什么想法吗?

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

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


Java
String.split()。因此,我认为这里有一些混乱。

其他响应者是正确的,split()以正则表达式作为参数,因此您必须首先解决这个问题。另一个问题是假设换行符与系统默认值相同。根据数据来源和程序运行的位置,这种假设可能不正确。

试试看

rows = tabDelimitedTable.split("[" + newLine + "]");
这应该可以解决正则表达式的问题

也不是很重要,但返回类型

System.getProperty("line.separator")
字符串,因此无需调用toString()。

请尝试以下操作:

rows = tabDelimitedTable.split("[\\r\\n]+");
无论输入中的行分隔符是什么,这都应该有效,并且将忽略空行。

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

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

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

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


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

您还可以组合使用2个扫描仪,一个用于逐行扫描文件,另一个用于扫描每行的令牌。下面是一个简单的用法示例,它将每一行分成一行。因此,整个文件将成为一个
列表

这可能比将整个文件读入一个巨大的
字符串,然后
拆分成行(然后
拆分成部分)更好

字符串文本
=“行1\tblah\tblah\tblah\n”
+“行2\t1\t2\t3\t4\r\n”
+“第3行\tA\tB\tC\r”
+“第4行”;
System.out.println(文本);
//第1排废话废话
//第2排1 2 3 4
//第3排A、B、C
//第4行
列表输入=新的ArrayList();
扫描仪sc=新扫描仪(文本);
while(sc.hasNextLine()){
Scanner lineSc=新扫描仪(sc.nextLine()).useDelimiter(“\t”);
列表行=新的ArrayList();
while(lineSc.hasNext()){
line.add(lineSc.next());
}
输入。添加(行);
}
系统输出打印项次(输入);
//[第1行,等等,等等],[第2行,第1行,第2行,第3行,第4行],[第3行,第A行,第B行,第C行],[第4行]]
另见
  • 有效Java第二版,第25项:首选列表而非数组
相关问题
  • -有许多使用示例

尝试
BufferedReader.readLine()
而不是所有这些复杂的操作。它将识别所有可能的线路终端。

Wow。。。“响应者”听起来很酷。从现在起,我将使用它。多行标志仅适用于在正则表达式中使用开始/结束标志(^和$)时。多行标志还会使“.”字符将行分隔符识别为匹配项。@James:noline,根据规范(和我的测试),多行“(?m)不会导致错误”。“匹配行分隔符的字符。这将是DOTALL标志“(?s)”Why.toString()?它已经是一个字符串,除非它为null,否则在这种情况下会得到一个NullPointerException。是的,我只是想确保我向.split()传递的是一个字符串而不是一个字符。我应该阅读关于.getProperty()方法的文档,但是编写.toString()比打开浏览器lol要快。我最初希望这个java程序也能在Mac/Linux上运行。因此,可以使用System.getProperty()方法。您仍然可以使用包含非系统默认行分隔符的输入。这个正则表达式将捕获所有组合,而不管平台和输入。谢谢,这很有效。我想我只是看了文件
    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]]