如何在 Java 中的文本文件中找到制表符行?

How do I find tabbed lines in text file in Java?

我有如下布局的文本文件。

Product Name
    HP Compaq Elite 8300 CMT

(HP Compaq Elite 8300 CMT 独占一行,前面有一个标签 space)

我正在尝试找到一种方法来逐行阅读并删除以制表符开头的行。首先,我将文件转换为字符串列表:

public static List<String> readFile2(File file) throws IOException {
    FileInputStream fis = new FileInputStream(file);
    List<String> list = new ArrayList<>();
    //Construct BufferedReader from InputStreamReader
    BufferedReader br = new BufferedReader(new InputStreamReader(fis));

    String line = null;
    while ((line = br.readLine()) != null) {
        list.add(br.readLine());
    }

    br.close();
    return list;
}

我在阅读列表时在循环中尝试了许多不同的语句,但没有返回正确的行:

for(int i=0; i<list.size(); i++)

    {
        if(list.get(i).indexOf("\u0009")>-1 || list.get(i).contains("\u0009") || list.get(i).indexOf((char)9)>-1 || list.get(i).startsWith(" ") || list.get(i).startsWith("\t"))
        {
        list.remove(i);
        }
    }

有什么建议吗?谢谢!

Java 的 String class has a startsWith 方法允许您测试字符串是否以给定前缀开头。您可以使用它来识别以制表符开头的行。通过使用它,您可以测试刚刚从缓冲区中读出的行,而不是将其添加到您的列表中。

String line = null;
while ((line = br.readLine()) != null) {
    if(!line.startsWith("\u0009")) {
        list.add(line);
    }
}

其他答案提出了(更好的1)替代方法,避免首先将匹配的行放入列表中。

这里解释了为什么您的版本不起作用:

for (int i = 0; i < list.size(); i++) {
    if (/* match line */) {
        list.remove(i);
    }
}

问题是,当您删除第 i 个列表元素时,较大索引处的所有元素都会得到 "renumbered";例如list.get(i + 1) 变成 list.get(i) 等等。

但是您接下来要做的是递增 i。所以...实际上...当您删除一个元素时,不会检查下一个元素。

正确的做法是:

int i = 0;
while (i < list.size()) {
    if (/* match line */) {
        list.remove(i);
    } else {
        i++;
    }
}

请注意,如果删除第 i 个元素,则不会增加 i


郑重声明,您使用的任何一项测试都足以匹配包含 TAB 的行。以多种不同的方式编写相同的测试并没有帮助。这对你来说是一个教训......


1 - 它更简单(代码更少),并且在处理大文件时效率也显着提高。从 ArrayList 中的任意位置删除元素是一个 O(N) 操作。