You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中CSV单元格正则匹配验证及MapReduce行为复现问题

解决CSV单元格正则校验的Java实现方案

看起来你已经走得挺远了——Map阶段的映射逻辑、FlightData对象都搞定了,剩下的单元格校验其实可以拆成「规则定义+校验逻辑+错误处理」三步来实现,下面给你具体的代码示例和思路:


第一步:先明确每个字段的正则校验规则

首先得根据你的FlightData字段,定义对应业务规则的正则表达式。比如假设你的CSV包含航班号、出发日期、延误分钟数、飞行里程这几个字段,规则可以这么写:

// 可根据你的实际业务需求调整这些正则
private static final String FLIGHT_NUM_REGEX = "^[A-Z]{2}\\d{3,4}$"; // 比如AA123或UA4567
private static final String DATE_REGEX = "^\\d{4}-\\d{2}-\\d{2}$"; // 标准YYYY-MM-DD格式
private static final String INTEGER_REGEX = "^\\d+$"; // 非负整数(延误分钟数不能是负数)
private static final String DECIMAL_REGEX = "^\\d+\\.\\d{1,2}$"; // 最多两位小数的里程数

第二步:封装通用的校验工具方法

把校验逻辑抽成工具方法,避免重复代码,还能统一处理空值场景:

/**
 * 校验单个CSV字段是否符合正则规则
 * @param fieldValue 单元格内容
 * @param regex 校验规则
 * @param allowEmpty 是否允许字段为空
 * @return 校验结果
 */
private boolean validateField(String fieldValue, String regex, boolean allowEmpty) {
    // 先处理空值情况
    if (fieldValue == null || fieldValue.trim().isEmpty()) {
        return allowEmpty;
    }
    // 非空则匹配正则
    return fieldValue.trim().matches(regex);
}

第三步:在CSV行处理流程中加入校验

在你拆分CSV行、映射到FlightData的环节,插入校验逻辑,校验不通过的话可以选择跳过该行、记录错误日志或者抛出异常:

try (BufferedReader br = new BufferedReader(new FileReader("your_flights.csv"))) {
    String header = br.readLine(); // 跳过表头
    String line;
    int lineNum = 1;

    while ((line = br.readLine()) != null) {
        lineNum++;
        String[] fields = line.split(",");
        
        // 先校验列数是否符合预期,避免数组越界
        if (fields.length != 4) {
            System.err.printf("第%d行列数错误,跳过该行:%s%n", lineNum, line);
            continue;
        }

        // 逐个字段校验
        boolean isFlightNumValid = validateField(fields[0], FLIGHT_NUM_REGEX, false);
        boolean isDateValid = validateField(fields[1], DATE_REGEX, false);
        boolean isDelayValid = validateField(fields[2], INTEGER_REGEX, true); // 允许延误分钟数为空
        boolean isMileValid = validateField(fields[3], DECIMAL_REGEX, false);

        if (!isFlightNumValid || !isDateValid || !isDelayValid || !isMileValid) {
            System.err.printf("第%d行字段校验失败,跳过该行:%s%n", lineNum, line);
            continue;
        }

        // 校验通过,映射到FlightData并存入HashMap
        FlightData flight = new FlightData();
        flight.setFlightNumber(fields[0].trim());
        flight.setDepartureDate(LocalDate.parse(fields[1].trim()));
        flight.setDelayMinutes(fields[2].isEmpty() ? 0 : Integer.parseInt(fields[2].trim()));
        flight.setMiles(Double.parseDouble(fields[3].trim()));

        // 模拟MapReduce的Map阶段,这里用航班号作为key示例
        yourHashMap.put(flight.getFlightNumber(), flight);
    }
} catch (IOException e) {
    e.printStackTrace();
}

进阶优化建议

  1. 处理带引号的CSV字段:如果你的CSV存在带逗号的字段(比如"New York, NY"),直接用split(",")会拆分错误,建议用OpenCSV这类成熟的CSV解析库,它能正确识别带引号的字段,还支持自定义校验器。
  2. 把校验整合到FlightData:可以把校验逻辑放到FlightData的构造方法或Setter里,创建对象时自动校验,比如:
public void setFlightNumber(String flightNumber) {
    if (!flightNumber.matches(FLIGHT_NUM_REGEX)) {
        throw new IllegalArgumentException("无效的航班号格式:" + flightNumber);
    }
    this.flightNumber = flightNumber;
}

这样能保证存入HashMap的FlightData对象都是合法的。

内容的提问来源于stack exchange,提问作者Glennismade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:48:18