
本文介绍一种正则表达式方案,用于安全移除字符串末尾的括号及其内容,但严格保留形如 (YYYY-YYYY) 的四位年份范围格式,避免误删有效日期信息。
本文介绍一种正则表达式方案,用于安全移除字符串末尾的括号及其内容,但严格保留形如 `(yyyy-yyyy)` 的四位年份范围格式,避免误删有效日期信息。
在文本清洗或数据预处理中,常需清理冗余括号标注(如注释、补充说明),但又不能破坏具有语义意义的结构化内容——例如 (1920-1988) 这类标准年份区间。核心挑战在于:仅匹配并删除位于字符串末尾、且不满足“四位数字-四位数字”模式的括号组。
✅ 正确的正则表达式方案
使用带负向先行断言(negative lookahead)的正则表达式,确保括号内容不构成合法年份范围,再精确锚定其位置:
s*( (?!d{4}p{Pd}d{4})) [^()]+ )s*$对应 Java 中 replaceAll 的完整用法示例:
String cleaned = input.replaceAll("\s*\((?!\d{4}\p{Pd}\d{4}\))[^()]+\)\s*$", "");? 关键组件解析:
- s*(:匹配行末可能存在的空格后紧跟的左括号;
- (?!d{4}p{Pd}d{4})):负向先行断言,确保后续不是「4位数字 + Unicode 连字符(如 -、–、—)+ 4位数字 + 右括号」;
- [^()]+:匹配至少一个非括号字符(避免空括号 ());
- )s*$:匹配右括号及末尾可选空格,并锚定到字符串结尾。
⚠️ 注意事项与边界情况
✅ 安全匹配:
foo bar (blah) → foo bar
foo bar (blah) blah (extra) → foo bar (blah) blah(仅删末尾括号)❌ 明确不匹配(保留原样):
some (content) data(括号不在末尾)
event (1920-1988)(符合年份范围模式)
report (1920–1988)(支持 Unicode 破折号,p{Pd} 覆盖)-
⚠️ 不处理的异常情形(需额外校验):
- 空括号 () → 因 [^()]+ 要求至少一个字符,故自动跳过;
- 嵌套括号 ((inner)) 或不配对括号 (unclosed → 不匹配,保持原样;
- 非4位年份如 (192-1988) 或 (1920-99) → 不触发排除逻辑,会被删除(符合设计预期)。
? 总结
该方案通过位置锚定($) + 结构排除(负向断言) + 内容约束([^()]+) 三重保障,实现高精度末尾括号清理。实际应用中建议配合单元测试覆盖典型场景,并注意 Java 字符串中反斜杠需双写(\s、\()。如需支持多行处理,可添加 Pattern.MULTILINE 标志。

















