【问题标题】:Remove all chars in a text file that should contain just numbers删除文本文件中应仅包含数字的所有字符
【发布时间】:2018-04-20 10:45:42
【问题描述】:

我找到了一个 java 程序,它可以将 java 中的两个文本文件相互比较,并使其列出不在两个文本文件中的所有行/条目。

package Exercise1;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class main {

public static void main(String[] args) throws IOException {

    String first = "migratielijst.txt";
    String second = "complete.txt";
    BufferedReader fBr = new BufferedReader(new FileReader(first));
    BufferedReader sBr = new BufferedReader(new FileReader(second));

    ArrayList<String> strings = new ArrayList<String>();

    while ((first = fBr.readLine()) != null) {
        strings.add(first);
        first.replaceAll("[^0-9.]", "");
    }
    fBr.close();

    while ((second = sBr.readLine()) != null) {
        if (!(strings.contains(second))) {
            System.out.println(second);
        } 
    }
    sBr.close();
}
}

我发现删除所有字符的行(如下)没有做我想做的事。

first.replaceAll("[^0-9.]", "");

假设文本文件如下所示:

8271910
8271911
//8271912
8271913
8271914
8271915

与之比较的文本文件如下所示:

8271910
8271911
8271912
8271913
8271914
8271915

它会列出 8271912,因为它在第一个文本文件中被注释掉了。 现在,如果我修改第一个文本文件并在其前面加上一个名称,我希望我的程序删除字符(比较时不考虑它们)。 示例:

Anya 8271910
8271911
//8271912
8271913
8271914
8271915

问题是我的程序返回这个:

8271910
8271912

我该如何解决这个问题?

【问题讨论】:

  • 我不明白你的比较逻辑,或者为什么它一定会起作用。这些 ID 是否以某种方式排序?如果不是,那么如何在不先读取两个文件的情况下报告两个文件中都没有的条目?
  • 在 Java 中,字符串是不可变的。查看第一个循环逻辑。
  • 另外,不要像使用 'first' 那样重用变量。使用有意义的名称,例如 migrateFilename。

标签: java bufferedreader string-comparison


【解决方案1】:

您的问题来自以下几行:

strings.add(first);
first.replaceAll("[^0-9.]", "");

在 Java 中,字符串是不可变的。因此,您正在做的是将 brut 字符串添加到您的列表中,然后创建一个带有所需修改的新字符串。但是新的字符串在你的程序中被忽略了。

这是一个快速修复:

strings.add(first.replaceAll("[^0-9.]", ""));

【讨论】:

    【解决方案2】:

    您最初的问题陈述似乎是说您想查找出现在一个文件或另一个文件中但不是同时出现在两个文件中的术语。就数据结构而言,最有意义的是集合,而不是列表,因为我们可以使用集合差异来获得您想要的结果。在下面的代码中,我将两个文件读入不同的集合,然后形成第三个集合,其中包含每个集合的差异。

    Set<String> s1 = new HashSet<>();
    Set<String> s1Copy = new HashSet<>();
    Set<String> s2 = new HashSet<>();
    
    String term;
    while ((term = fBr.readLine()) != null) {
        s1.add(term);
        s1Copy.add(term);
    }
    fBr.close();
    
    while ((term = sBr.readLine()) != null) {
        s2.add(term);
    }
    sBr.close();
    
    Set<String> unique = new HashSet<>();
    unique.add(s1.removeAll(s2));
    unique.add(s2.removeAll(s1Copy));
    
    System.out.println("Unique terms:");
    for (String s : unique) {
        System.out.println(s);
    }
    

    【讨论】:

    • s1.removeAll(s2) -> 返回一个布尔值。你不能添加(它应该是addAll,而不是添加)。当您执行 s1.removeAll(s2) 时,执行 s2.removeAll(s1) 毫无意义,因为现在已知 s1 将不包含 s2 的任何成员。干杯。
    • 这真的很难看,很抱歉我这么说:) 我更喜欢这样的东西:unique.addAll(s1);唯一的.addAll(s2); unique.removeIf(x -> s1.contains(x) && s2.contains(x));
    • 太痛苦了兄弟。我的主要目标只是指出业务需求可以使用集合逻辑而不是列表比较。
    • 只是为了澄清 Set.retainAll(Collection c) -> 删除所有元素,但包含在两个集合(交集)中的元素除外。
    【解决方案3】:

    你可以试试这样的

    anyString = anyString.replaceAll("\\D+",""); 
    

    【讨论】:

      猜你喜欢
      • 2020-07-02
      • 1970-01-01
      • 2011-09-05
      • 2020-07-27
      • 2013-08-19
      • 1970-01-01
      • 2018-06-28
      • 1970-01-01
      相关资源
      最近更新 更多