Java Regex从文件中检索双倍数字,但忽略带有多个点的数字

Java Regex从文件中检索双倍数字,但忽略带有多个点的数字,java,regex,Java,Regex,检索文件中的所有双精度数字并返回总和,但避免使用多个点的值 测试用例: 归档 12.3123.45,19,2.16.8.1.1 输出 预期产量->154.75 我的输出->166.01 -?\\d+\.?\\d*这将检索所有双精度数字,但忽略带有多个点的数字失败 FileReader reader = new FileReader(filename); BufferedReader in = new BufferedReader(reader); String line; while ((li

检索文件中的所有双精度数字并返回总和,但避免使用多个点的值

测试用例:

归档

12.3123.45,19,2.16.8.1.1

输出

预期产量->154.75 我的输出->166.01

-?\\d+\.?\\d*
这将检索所有双精度数字,但忽略带有多个点的数字失败

FileReader reader = new FileReader(filename);
BufferedReader in = new BufferedReader(reader);
String line;

while ((line = in.readLine()) != null) {
    Pattern pattern = Pattern.compile("-?\\d+\\.?\\d*");
    Matcher matcher = pattern.matcher(line);
    while (matcher.find()) {
        String x = matcher.group(0);
        y = Double.parseDouble(x);
        sum = sum + y;
    }
}
预期输出->154.75我的输出->166.01

错误数字的子字符串实际有效的问题。“1.2.3”应该被忽略,但如果你只是盲目地寻找有效数字,那么这个数字可能包含“1.2”或“2.3”作为有效数字

有两种方法可以避免这种情况:

  • 用已知的分隔符“,”拆分该行,并根据每个零件的有效性或无效性进行变量化
  • 搜索有效号码和无效号码,并丢弃无效号码

    为此,您可以使用类似于
    -?\d+\.?\d*(\.d*)?
    的正则表达式,并在匹配组为非空时放弃结果

  • 你可以用

    -?(?<!\d)(?<!\d\.)\d*\.?\d+(?!\.?\d)
    

    对不起,我看不懂这些正则表达式,它们对普通人来说太复杂了

    为什么要使用复杂的正则表达式,其他开发人员在阅读时会遇到困难。如果我不得不调试那段代码,我会讨厌它的

    我觉得下面这样的内容更具可读性,还可以减少出错的机会,并易于调试:

    public double sumFile(String filename) {
        try (Stream<String> linesStream = Files.lines(Paths.get(filename))) {
            return linesStream.mapToDouble(this::sumLine).sum();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }
    
    private double sumLine(String line) {
        return Arrays.stream(line.split(","))
                .filter(e -> e.split("\\.").length <= 2)
                .mapToDouble(Double::parseDouble)
                .sum();
    }
    
    公共双文件(字符串文件名){
    try(Stream-linessstream=Files.lines(path.get(filename))){
    返回行stream.mapToDouble(this::sumLine.sum();
    }捕获(IOE异常){
    e、 printStackTrace();
    }
    返回0;
    }
    专用双槽线(串线){
    返回Arrays.stream(line.split(“,”))
    .filter(e->e.split(“\\”)。长度使用
    “-?(?)?
    
    public double sumFile(String filename) {
        try (Stream<String> linesStream = Files.lines(Paths.get(filename))) {
            return linesStream.mapToDouble(this::sumLine).sum();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0;
    }
    
    private double sumLine(String line) {
        return Arrays.stream(line.split(","))
                .filter(e -> e.split("\\.").length <= 2)
                .mapToDouble(Double::parseDouble)
                .sum();
    }