
本文介绍如何用java灵活解析格式各异的营业时间字符串(如“monday–friday: 8am–5pm”或“24/7”),通过分段拆解、正则匹配与语义归一化,将非结构化文本可靠映射为按星期索引的结构化数据。
本文介绍如何用java灵活解析格式各异的营业时间字符串(如“monday–friday: 8am–5pm”或“24/7”),通过分段拆解、正则匹配与语义归一化,将非结构化文本可靠映射为按星期索引的结构化数据。
处理来自真实业务场景(如Excel导入)的营业时间字段,是典型的非结构化文本解析挑战:数据格式高度不统一,无法预设单一模板,且人工清洗成本过高。核心思路不是追求“一个正则通吃”,而是构建分层解析流水线——先粗粒度切分语义单元,再逐单元识别日期范围与时段,最后归一化为标准模型。
第一步:按语义边界分割原始字符串
逗号(,)是最稳定的分隔符,但需兼顾空格变体和连字符连接(如 "Monday 4AM-8PM-Saturday 4AM-8PM")。推荐使用增强型分割:
String[] segments = input.trim()
.replaceAll("([a-zA-Z])\s*–\s*([a-zA-Z])", "$1; $2") // 将“Monday–Friday”转为“Monday; Friday”
.replaceAll("\s*,\s*", ", ") // 统一逗号空格
.split(", ");此步将输入分解为逻辑片段,例如 "Monday – Friday: 8am – 5pm, Saturday Closed" → ["Monday – Friday: 8am – 5pm", "Saturday Closed"]。
第二步:逐片段识别日期模式与状态
对每个片段,采用多策略匹配(优先级从高到低):
立即学习“Java免费学习笔记(深入)”;
- 全时可用标识:直接匹配 "24/7"、"Open 24 hours" 等;
-
单日明确声明:如 "Mon 7:15 AM - 4:00 PM" 或 "Friday Closed",用正则提取:
Pattern singleDay = Pattern.compile("(?i)(mon|tue|wed|thu|fri|sat|sun)(?:day)?\s+(\d[^,]+)", Pattern.CASE_INSENSITIVE); -
多日范围声明:如 "Monday – Friday: 8am – 5pm",需解析起止日并生成对应天数列表:
Pattern rangePattern = Pattern.compile("(?i)(mon|tue|wed|thu|fri|sat|sun)(?:day)?\s*–\s*(mon|tue|wed|thu|fri|sat|sun)(?:day)?\s*:\s*(.+)");
⚠️ 注意:正则中的 (?i) 启用忽略大小写,(?:nes|rs|ur)?day 覆盖 Monday/Tuesday/Saturday 等缩写变体;时间部分建议用 (\d{1,2}(?::\d{2})?\s*[AP]M?|\d{1,2}\s*[-–]\s*\d{1,2}(?::\d{2})?\s*[AP]M?) 增强鲁棒性。
第三步:归一化存储与扩展处理
定义标准数据结构,避免分散变量(如 monHours):
public class BusinessHours {
private final Map<DayOfWeek, String> hours = new EnumMap<>(DayOfWeek.class);
public void setHours(DayOfWeek day, String timeSpec) {
hours.put(day, "closed".equalsIgnoreCase(timeSpec) ? "closed" : normalizeTime(timeSpec));
}
private String normalizeTime(String raw) {
return raw.toUpperCase().replace(" ", "")
.replace("AM", " AM").replace("PM", " PM");
}
}调用示例:
BusinessHours result = new BusinessHours();
parseAndPopulate("Monday – Friday: 8am – 5pm, Saturday Closed, Sunday Closed", result);
// result.hours.get(DayOfWeek.MONDAY) → "8 AM - 5 PM"关键总结
- 拒绝过度依赖单一正则:复杂文本需组合策略(分割→分类→匹配→归一);
- 优先处理高频特例(如 "24/7"、"Closed")可大幅提升覆盖率;
- 始终验证边界情况:空格、中文破折号(– vs -)、无空格时间("4AM-8PM");
- 预留扩展接口:未来可接入NLP库(如Apache OpenNLP)处理更模糊表述。
最终目标不是完美覆盖100%边缘格式,而是以80/20原则,用可维护的代码解决95%真实数据,剩余异常项交由人工复核——这才是生产环境中的务实之道。


















