【问题标题】:How to find and remove strings with case insensitive match?如何查找和删除不区分大小写的字符串?
【发布时间】:2016-04-05 23:58:24
【问题描述】:

在 Java 中,我有一个文件包含以下行:

abc
cbd
CFG
...

如果任何行与字符串匹配,我想从文件中删除 CFG,这可能是“cfg”、“Cfg”或其他不区分大小写的变体。

如果我将文件读入一个集合,我该如何实现呢?将文件读入 List 似乎更可行。

【问题讨论】:

  • 您可以将字符串大写并插入到集合中。
  • String.equalsIgnoreCase(String str)
  • 那你打印出来的时候把原来的箱子都丢了,这不是我需要的。

标签: java


【解决方案1】:

以下是所需代码的“lambda 版本”。感谢@Sam 提出关于重新引发任何抑制的 PrintWriter IOException 的重要观点。

Path in_file = Paths.get("infile");
Path out_file = Paths.get("outfile");
try (PrintWriter pw = new PrintWriter(out_file.toFile())) {
    Files.lines(in_file)
         .filter(line -> !line.equalsIgnoreCase("cfg"))
         .forEach(pw::println);
    if (pw.checkError()) {
        throw new IOException("Exception(s) occurred in PrintWriter");
    }
}

如果您需要就地修改文件,那么在读取文件的同时写入文件会有些困难。您可以先将其全部读入内存。

Path path = new Path("filename");
List<String> lines = Files.lines(path)
                          .filter(line -> !line.equalsIgnoreCase("cfg"))
                          .collect(Collectors.toList());

try(PrintWriter pw = new PrintWriter(path.toFile())) {
    lines.forEach(pw::println);
    if (pw.checkError()) {
        throw new IOException("Exception(s) occurred in PrintWriter");
    }
}

最后,以防万一,一个与 Java 7 兼容的非 lambda 解决方案:

Path in_file = Paths.get("infile");
Path out_file = Paths.get("outfile");
try (BufferReader reader = Files.newBufferedReader(in_file);
         PrintWriter pw = new PrintWriter(out_file.toFile())) {

    String line;
    while((line = reader.readline()) != null) {
        if (!line.equalsIgnoreCase("cfg")) {
            pw.println(line);
        }
    }
    if (pw.checkError()) {
        throw new IOException("Exception(s) occurred in PrintWriter");
    }
}

【讨论】:

  • 不错!我不知道!
  • @Sam - 是的,方便PrintWriter。现在,如果他们只有一个.collect(toFile(path)) 收集器,这可能是一个“单线”!
  • 虽然我刚刚阅读了更多关于它的内容,但它确实吞下了异常。我想如果它抛出一个 RuntimeException 用于生产用途我会更高兴,所以如果它有点错误,我至少会在日志中结束一些东西。
  • @Sam - 您可以在 try { } 块的末尾调用 if (pw.checkError()) { throw new IOException("Stream had errors"); }。也许信息量不大,但实际上您只关心存在问题,以及大部分发生在哪里。
  • 是的,我意识到这将是妥协:)
【解决方案2】:

这样的?

try (BufferedReader bf = new BufferedReader(new FileReader(new File("PATH TO FILE")));
     BufferedWriter bw = new bw(new FileWriter(new File("PATH TO NEW FILE")))) {
  bf.lines()
      .filter(line -> !line.equalsIgnoreCase("cfg"))
      .forEach(line -> {
        try {
          bw.write(line);
        } catch (IOException e) {
          e.printStackTrace();
        }
  });
}

唯一丑陋的事情是需要两次尝试,因为不允许从 lambdas 抛出异常。

【讨论】:

  • A PrintWriter 为您抑制异常。看我的回答。
  • BufferedReader#lines() 从行流中删除换行符。您需要使用bw.write(line).newLine(); 重新添加它。
  • 哎呀! bw.write(line); bw.newLine(); 你不能链接 BufferedWriter 方法。
【解决方案3】:

您可以在列表中搜索字符串并使用位置删除它。

public List<String> removeItemInListIgnoreCase(List<String> items, String itemToRemove){
        if(CollectionUtils.isEmpty(items)) 
        return new ArrayList<String>();
        for(int i=0; i<items.size();i++) {
            if(items.get(i).equalsIgnoreCase(itemToRemove)) {
                items.remove(i);
            }
        }
        return items;
    }

【讨论】:

    猜你喜欢
    • 2011-08-18
    • 2011-10-26
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多